diff --git a/.github/workflows/IKVM.yml b/.github/workflows/IKVM.yml
index f44b1e07b2..1ec55ca878 100644
--- a/.github/workflows/IKVM.yml
+++ b/.github/workflows/IKVM.yml
@@ -240,6 +240,16 @@ jobs:
path: /tmp/tests--IKVM.Reflection.Tests.tar.gz
- name: Delete Tests (IKVM.Reflection.Tests)
run: rm /tmp/tests--IKVM.Reflection.Tests.tar.gz
+ - name: Package Tests (IKVM.CoreLib.Tests)
+ run: tar czvf /tmp/tests--IKVM.CoreLib.Tests.tar.gz tests/IKVM.CoreLib.Tests
+ working-directory: dist
+ - name: Upload Tests (IKVM.CoreLib.Tests)
+ uses: actions/upload-artifact@v4
+ with:
+ name: tests--IKVM.CoreLib.Tests
+ path: /tmp/tests--IKVM.CoreLib.Tests.tar.gz
+ - name: Delete Tests (IKVM.CoreLib.Tests)
+ run: rm /tmp/tests--IKVM.CoreLib.Tests.tar.gz
- name: Package Tests (IKVM.Tests)
run: tar czvf /tmp/tests--IKVM.Tests.tar.gz tests/IKVM.Tests
working-directory: dist
@@ -378,8 +388,9 @@ jobs:
$tfm += @( "net6.0" )
}
- $run = @(
+ $run = (
"IKVM.Reflection.Tests",
+ "IKVM.CoreLib.Tests",
"IKVM.Tests",
"IKVM.Java.Tests",
"IKVM.Tools.Exporter.Tests",
diff --git a/IKVM.deps.targets b/IKVM.deps.targets
index b5b022c12b..7f0a15af2b 100644
--- a/IKVM.deps.targets
+++ b/IKVM.deps.targets
@@ -2,7 +2,9 @@
-
+
+
+
diff --git a/IKVM.refs.targets b/IKVM.refs.targets
index ff52d30390..54c246820f 100644
--- a/IKVM.refs.targets
+++ b/IKVM.refs.targets
@@ -5,6 +5,11 @@
+
+ true
+ all
+ IkvmLibsItem
+
true
all
diff --git a/IKVM.sln b/IKVM.sln
index 346f617c4f..d370cca6cc 100644
--- a/IKVM.sln
+++ b/IKVM.sln
@@ -341,7 +341,9 @@ Project("{6DE1C62B-E8D7-451A-8734-87EAEB46E35B}") = "libsspi_bridge", "src\libss
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IKVM.CoreLib", "src\IKVM.CoreLib\IKVM.CoreLib.csproj", "{C6556982-85B8-4E58-A693-1239D4823BD7}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IKVM.Tools.Core", "src\IKVM.Tools.Core\IKVM.Tools.Core.csproj", "{0D74BDB7-F1FE-4E9E-B195-640C66DA19D2}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IKVM.Tools.Core", "src\IKVM.Tools.Core\IKVM.Tools.Core.csproj", "{0D74BDB7-F1FE-4E9E-B195-640C66DA19D2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IKVM.CoreLib.Tests", "src\IKVM.CoreLib.Tests\IKVM.CoreLib.Tests.csproj", "{21179656-9D00-45C9-A8BF-50E456AA29D4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -921,6 +923,10 @@ Global
{0D74BDB7-F1FE-4E9E-B195-640C66DA19D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D74BDB7-F1FE-4E9E-B195-640C66DA19D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D74BDB7-F1FE-4E9E-B195-640C66DA19D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {21179656-9D00-45C9-A8BF-50E456AA29D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {21179656-9D00-45C9-A8BF-50E456AA29D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {21179656-9D00-45C9-A8BF-50E456AA29D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {21179656-9D00-45C9-A8BF-50E456AA29D4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/IKVM.CoreLib.Tests/IKVM.CoreLib.Tests.csproj b/src/IKVM.CoreLib.Tests/IKVM.CoreLib.Tests.csproj
new file mode 100644
index 0000000000..7376cc8ede
--- /dev/null
+++ b/src/IKVM.CoreLib.Tests/IKVM.CoreLib.Tests.csproj
@@ -0,0 +1,16 @@
+
+
+ net472;net6.0;net7.0;net8.0
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs
new file mode 100644
index 0000000000..c683fdbb12
--- /dev/null
+++ b/src/IKVM.CoreLib.Tests/Symbols/IkvmReflection/IkvmReflectionSymbolTests.cs
@@ -0,0 +1,199 @@
+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();
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs
new file mode 100644
index 0000000000..37b66bf096
--- /dev/null
+++ b/src/IKVM.CoreLib.Tests/Symbols/Reflection/ReflectionSymbolTests.cs
@@ -0,0 +1,147 @@
+using System;
+
+using FluentAssertions;
+
+using IKVM.CoreLib.Symbols.Reflection;
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace IKVM.CoreLib.Tests.Symbols.Reflection
+{
+
+ [TestClass]
+ public class ReflectionSymbolTests
+ {
+
+ class Foo
+ {
+ T? field;
+ }
+
+ [TestMethod]
+ public void SameTypeShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(object));
+ var s2 = c.GetOrCreateTypeSymbol(typeof(object));
+ s1.Should().BeOfType();
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public void GenericTypeDefinitionShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(Foo<>));
+ var s2 = c.GetOrCreateTypeSymbol(typeof(Foo<>));
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public void GenericTypeShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(Foo));
+ var s2 = c.GetOrCreateTypeSymbol(typeof(Foo));
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public void ArrayTypeShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(object[,]));
+ var s2 = c.GetOrCreateTypeSymbol(typeof(object[,]));
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public void SZArrayTypeShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(object[]));
+ var s2 = c.GetOrCreateTypeSymbol(typeof(object[]));
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public unsafe void PointerTypeShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(int*));
+ var s2 = c.GetOrCreateTypeSymbol(typeof(int*));
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public unsafe void ByRefTypeShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(int).MakeByRefType());
+ var s2 = c.GetOrCreateTypeSymbol(typeof(int).MakeByRefType());
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public void EnumTypeShouldBeSame()
+ {
+ var c = new ReflectionSymbolContext();
+ var s1 = c.GetOrCreateTypeSymbol(typeof(AttributeTargets));
+ var s2 = c.GetOrCreateTypeSymbol(typeof(AttributeTargets));
+ s1.Should().BeSameAs(s2);
+ }
+
+ [TestMethod]
+ public void CanGetType()
+ {
+ var c = new ReflectionSymbolContext();
+ var s = c.GetOrCreateTypeSymbol(typeof(object));
+ s.Name.Should().Be("Object");
+ s.FullName.Should().Be("System.Object");
+ }
+
+ [TestMethod]
+ public void CanGetFieldOfGenericTypeDefinition()
+ {
+ var c = new ReflectionSymbolContext();
+ var s = c.GetOrCreateTypeSymbol(typeof(Foo<>));
+ 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 c = new ReflectionSymbolContext();
+ var s = c.GetOrCreateTypeSymbol(typeof(Foo));
+ 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(typeof(int)));
+ }
+
+ [TestMethod]
+ public void CanGetMethod()
+ {
+ var c = new ReflectionSymbolContext();
+ var s = c.GetOrCreateTypeSymbol(typeof(object));
+ var m = s.GetMethod("ToString");
+ m.Name.Should().Be("ToString");
+ m.ReturnType.Should().BeSameAs(c.GetOrCreateTypeSymbol(typeof(string)));
+ m.ReturnParameter.ParameterType.Should().BeSameAs(c.GetOrCreateTypeSymbol(typeof(string)));
+ m.IsGenericMethod.Should().BeFalse();
+ m.IsGenericMethodDefinition.Should().BeFalse();
+ m.IsPublic.Should().BeTrue();
+ m.IsPrivate.Should().BeFalse();
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/IKVM.CoreLib.csproj b/src/IKVM.CoreLib/IKVM.CoreLib.csproj
index 8da6ba6d92..cede1bd120 100644
--- a/src/IKVM.CoreLib/IKVM.CoreLib.csproj
+++ b/src/IKVM.CoreLib/IKVM.CoreLib.csproj
@@ -7,6 +7,7 @@
+
@@ -18,15 +19,24 @@
+
+
+
+
+
+
+
+
+
DiagnosticEvent.g.cs
diff --git a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbol.cs b/src/IKVM.CoreLib/Symbols/CustomAttributeSymbol.cs
new file mode 100644
index 0000000000..dbdab0f3cb
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/CustomAttributeSymbol.cs
@@ -0,0 +1,12 @@
+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/CustomAttributeSymbolNamedArgument.cs b/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolNamedArgument.cs
new file mode 100644
index 0000000000..c01598e24c
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolNamedArgument.cs
@@ -0,0 +1,10 @@
+namespace IKVM.CoreLib.Symbols
+{
+
+ readonly record struct CustomAttributeSymbolNamedArgument(
+ bool IsField,
+ IMemberSymbol MemberInfo,
+ string MemberName,
+ CustomAttributeSymbolTypedArgument TypedValue);
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolTypedArgument.cs b/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolTypedArgument.cs
new file mode 100644
index 0000000000..0f56df5a32
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/CustomAttributeSymbolTypedArgument.cs
@@ -0,0 +1,8 @@
+namespace IKVM.CoreLib.Symbols
+{
+
+ readonly record struct CustomAttributeSymbolTypedArgument(
+ ITypeSymbol ArgumentType,
+ object? Value);
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs
new file mode 100644
index 0000000000..1b0817f280
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IAssemblySymbol.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ interface IAssemblySymbol : ISymbol, ICustomAttributeSymbolProvider
+ {
+
+ IEnumerable DefinedTypes { get; }
+
+ IMethodSymbol? EntryPoint { get; }
+
+ IEnumerable ExportedTypes { get; }
+
+ string? FullName { get; }
+
+ string ImageRuntimeVersion { get; }
+
+ IModuleSymbol ManifestModule { get; }
+
+ IEnumerable Modules { get; }
+
+ ITypeSymbol[] GetExportedTypes();
+
+ IModuleSymbol? GetModule(string name);
+
+ IModuleSymbol[] GetModules();
+
+ IModuleSymbol[] GetModules(bool getResourceModules);
+
+ AssemblyName GetName();
+
+ AssemblyName GetName(bool copiedName);
+
+ AssemblyName[] GetReferencedAssemblies();
+
+ ITypeSymbol? GetType(string name, bool throwOnError);
+
+ ITypeSymbol? GetType(string name, bool throwOnError, bool ignoreCase);
+
+ ITypeSymbol? GetType(string name);
+
+ ITypeSymbol[] GetTypes();
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/IConstructorSymbol.cs
new file mode 100644
index 0000000000..3b5d8a4c23
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IConstructorSymbol.cs
@@ -0,0 +1,14 @@
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Discovers the attributes of a class constructor and provides access to constructor metadata.
+ ///
+ interface IConstructorSymbol : IMethodBaseSymbol
+ {
+
+
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs b/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs
new file mode 100644
index 0000000000..d7354b219e
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/ICustomAttributeSymbolProvider.cs
@@ -0,0 +1,32 @@
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Provides custom attributes for reflection objects that support them.
+ ///
+ 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();
+
+ ///
+ /// 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);
+
+ ///
+ /// Indicates whether one or more instance of is defined on this member.
+ ///
+ ///
+ ///
+ bool IsDefined(ITypeSymbol attributeType);
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IEventSymbol.cs b/src/IKVM.CoreLib/Symbols/IEventSymbol.cs
new file mode 100644
index 0000000000..220a74891c
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IEventSymbol.cs
@@ -0,0 +1,96 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Discovers the attributes of an event and provides access to event metadata.
+ ///
+ interface IEventSymbol : IMemberSymbol
+ {
+
+ ///
+ /// Gets the attributes for this event.
+ ///
+ EventAttributes Attributes { get; }
+
+ ///
+ /// Gets the object of the underlying event-handler delegate associated with this event.
+ ///
+ ITypeSymbol? EventHandlerType { get; }
+
+ ///
+ /// Gets a value indicating whether the has a name with a special meaning.
+ ///
+ bool IsSpecialName { get; }
+
+ ///
+ /// Returns the method used to add an event handler delegate to the event source.
+ ///
+ IMethodSymbol? AddMethod { get; }
+
+ ///
+ /// Returns the method used to remove an event handler delegate from the event source.
+ ///
+ IMethodSymbol? RemoveMethod { get; }
+
+ ///
+ /// Returns the method that is called when the event is raised.
+ ///
+ IMethodSymbol? RaiseMethod { get; }
+
+ ///
+ /// Returns the method used to add an event handler delegate to the event source.
+ ///
+ ///
+ IMethodSymbol? GetAddMethod();
+
+ ///
+ /// Returns the method used to add an event handler delegate to the event source, specifying whether to return non-public methods.
+ ///
+ ///
+ ///
+ IMethodSymbol? GetAddMethod(bool nonPublic);
+
+ ///
+ /// Returns the method used to remove an event handler delegate from the event source.
+ ///
+ ///
+ IMethodSymbol? GetRemoveMethod();
+
+ ///
+ /// When overridden in a derived class, retrieves the object for removing a method of the event, specifying whether to return non-public methods.
+ ///
+ ///
+ ///
+ IMethodSymbol? GetRemoveMethod(bool nonPublic);
+
+ ///
+ /// Returns the method that is called when the event is raised.
+ ///
+ ///
+ IMethodSymbol? GetRaiseMethod();
+
+ ///
+ /// When overridden in a derived class, returns the method that is called when the event is raised, specifying whether to return non-public methods.
+ ///
+ ///
+ ///
+ IMethodSymbol? GetRaiseMethod(bool nonPublic);
+
+ ///
+ /// Returns the public methods that have been associated with an event in metadata using the .other directive.
+ ///
+ ///
+ IMethodSymbol[] GetOtherMethods();
+
+ ///
+ /// Returns the methods that have been associated with the event in metadata using the .other directive, specifying whether to include non-public methods.
+ ///
+ ///
+ ///
+ IMethodSymbol[] GetOtherMethods(bool nonPublic);
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/IFieldSymbol.cs
new file mode 100644
index 0000000000..1eee20fe92
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IFieldSymbol.cs
@@ -0,0 +1,102 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Discovers the attributes of a field and provides access to field metadata.
+ ///
+ interface IFieldSymbol : IMemberSymbol
+ {
+
+ ///
+ /// Gets the attributes associated with this field.
+ ///
+ FieldAttributes Attributes { get; }
+
+ ///
+ /// Gets the type of this field object.
+ ///
+ ITypeSymbol FieldType { get; }
+
+ ///
+ /// Gets a value indicating whether the potential visibility of this field is described by ; that is, the field is visible at most to other types in the same assembly, and is not visible to derived types outside the assembly.
+ ///
+ bool IsAssembly { get; }
+
+ ///
+ /// Gets a value indicating whether the visibility of this field is described by ; that is, the field is visible only within its class and derived classes.
+ ///
+ bool IsFamily { get; }
+
+ ///
+ /// Gets a value indicating whether the visibility of this field is described by ; that is, the field can be accessed from derived classes, but only if they are in the same assembly.
+ ///
+ bool IsFamilyAndAssembly { get; }
+
+ ///
+ /// Gets a value indicating whether the potential visibility of this field is described by ; that is, the field can be accessed by derived classes wherever they are, and by classes in the same assembly.
+ ///
+ bool IsFamilyOrAssembly { get; }
+
+ ///
+ /// Gets a value indicating whether the field can only be set in the body of the constructor.
+ ///
+ bool IsInitOnly { get; }
+
+ ///
+ /// Gets a value indicating whether the value is written at compile time and cannot be changed.
+ ///
+ bool IsLiteral { get; }
+
+ ///
+ /// Gets a value indicating whether this field has the NotSerialized attribute.
+ ///
+ bool IsNotSerialized { get; }
+
+ ///
+ /// Gets a value indicating whether the corresponding PinvokeImpl attribute is set in FieldAttributes.
+ ///
+ bool IsPinvokeImpl { get; }
+
+ ///
+ /// Gets a value indicating whether the field is private.
+ ///
+ bool IsPrivate { get; }
+
+ ///
+ /// Gets a value indicating whether the field is public.
+ ///
+ bool IsPublic { get; }
+
+ ///
+ /// Gets a value indicating whether the corresponding SpecialName attribute is set in the FieldAttributes enumerator.
+ ///
+ bool IsSpecialName { get; }
+
+ ///
+ /// Gets a value indicating whether the field is static.
+ ///
+ bool IsStatic { get; }
+
+ ///
+ /// Returns a literal value associated with the field by a compiler.
+ ///
+ ///
+ object? GetRawConstantValue();
+
+ ///
+ /// Gets an array of types that identify the optional custom modifiers of the field.
+ ///
+ ///
+ ITypeSymbol[] GetOptionalCustomModifiers();
+
+ ///
+ /// Gets an array of types that identify the required custom modifiers of the property.
+ ///
+ ///
+ ITypeSymbol[] GetRequiredCustomModifiers();
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IMemberSymbol.cs
new file mode 100644
index 0000000000..0613ff1000
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IMemberSymbol.cs
@@ -0,0 +1,39 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Obtains information about the attributes of a member and provides access to member metadata.
+ ///
+ interface IMemberSymbol : ISymbol, ICustomAttributeSymbolProvider
+ {
+
+ ///
+ /// Gets the module in which the type that declares the member represented by the current is defined.
+ ///
+ IModuleSymbol Module { get; }
+
+ ///
+ /// Gets the class that declares this member.
+ ///
+ ITypeSymbol? DeclaringType { get; }
+
+ ///
+ /// When overridden in a derived class, gets a value indicating the type of the member - method, constructor, event, and so on.
+ ///
+ MemberTypes MemberType { get; }
+
+ ///
+ /// Gets a value that identifies a metadata element.
+ ///
+ int MetadataToken { get; }
+
+ ///
+ /// Gets the name of the current member.
+ ///
+ string Name { get; }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs
new file mode 100644
index 0000000000..00b6144a0e
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IMethodBaseSymbol.cs
@@ -0,0 +1,127 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Provides information about methods and constructors.
+ ///
+ interface IMethodBaseSymbol : IMemberSymbol
+ {
+
+ ///
+ /// Gets the attributes associated with this method.
+ ///
+ MethodAttributes Attributes { get; }
+
+ ///
+ /// Gets a value indicating the calling conventions for this method.
+ ///
+ CallingConventions CallingConvention { get; }
+
+ ///
+ /// Gets a value indicating whether the generic method contains unassigned generic type parameters.
+ ///
+ bool ContainsGenericParameters { get; }
+
+ ///
+ /// Gets a value indicating whether the method is abstract.
+ ///
+ bool IsAbstract { get; }
+
+ ///
+ /// Gets a value indicating whether the potential visibility of this method or constructor is described by Assembly; that is, the method or constructor is visible at most to other types in the same assembly, and is not visible to derived types outside the assembly.
+ ///
+ bool IsAssembly { get; }
+
+ ///
+ /// Gets a value indicating whether the method is a constructor.
+ ///
+ bool IsConstructor { get; }
+
+ ///
+ /// Gets a value indicating whether the visibility of this method or constructor is described by Family; that is, the method or constructor is visible only within its class and derived classes.
+ ///
+ bool IsFamily { get; }
+
+ ///
+ /// Gets a value indicating whether the visibility of this method or constructor is described by FamANDAssem; that is, the method or constructor can be called by derived classes, but only if they are in the same assembly.
+ ///
+ bool IsFamilyAndAssembly { get; }
+
+ ///
+ /// Gets a value indicating whether the potential visibility of this method or constructor is described by FamORAssem; that is, the method or constructor can be called by derived classes wherever they are, and by classes in the same assembly.
+ ///
+ bool IsFamilyOrAssembly { get; }
+
+ ///
+ /// Gets a value indicating whether this method is final.
+ ///
+ bool IsFinal { get; }
+
+ ///
+ /// Gets a value indicating whether the method is generic.
+ ///
+ bool IsGenericMethod { get; }
+
+ ///
+ /// Gets a value indicating whether the method is a generic method definition.
+ ///
+ bool IsGenericMethodDefinition { get; }
+
+ ///
+ /// Gets a value indicating whether only a member of the same kind with exactly the same signature is hidden in the derived class.
+ ///
+ bool IsHideBySig { get; }
+
+ ///
+ /// Gets a value indicating whether this member is private.
+ ///
+ bool IsPrivate { get; }
+
+ ///
+ /// Gets a value indicating whether this is a public method.
+ ///
+ bool IsPublic { get; }
+
+ ///
+ /// Gets a value indicating whether the method is static.
+ ///
+ bool IsStatic { get; }
+
+ ///
+ /// Gets a value indicating whether the method is virtual.
+ ///
+ bool IsVirtual { get; }
+
+ ///
+ /// Gets a value indicating whether this method has a special name.
+ ///
+ bool IsSpecialName { get; }
+
+ ///
+ /// Gets the flags that specify the attributes of a method implementation.
+ ///
+ MethodImplAttributes MethodImplementationFlags { get; }
+
+ ///
+ /// 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();
+
+ ///
+ /// When overridden in a derived class, gets the parameters of the specified method or constructor.
+ ///
+ ///
+ IParameterSymbol[] GetParameters();
+
+ ///
+ /// When overridden in a derived class, returns the MethodImplAttributes flags.
+ ///
+ ///
+ MethodImplAttributes GetMethodImplementationFlags();
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs
new file mode 100644
index 0000000000..08d2f8dcb6
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IMethodSymbol.cs
@@ -0,0 +1,46 @@
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Discovers the attributes of a method and provides access to method metadata.
+ ///
+ interface IMethodSymbol : IMethodBaseSymbol
+ {
+
+ ///
+ /// Gets a object that contains information about the return type of the method, such as whether the return type has custom modifiers.
+ ///
+ IParameterSymbol ReturnParameter { get; }
+
+ ///
+ /// Gets the return type of this method.
+ ///
+ ITypeSymbol ReturnType { get; }
+
+ ///
+ /// Gets the custom attributes for the return type.
+ ///
+ ICustomAttributeSymbolProvider 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.
+ ///
+ ///
+ IMethodSymbol GetBaseDefinition();
+
+ ///
+ /// Returns a object that represents a generic method definition from which the current method can be constructed.
+ ///
+ ///
+ IMethodSymbol GetGenericMethodDefinition();
+
+ ///
+ /// Substitutes the elements of an array of types for the type parameters of the current generic method definition, and returns a MethodInfo object representing the resulting constructed method.
+ ///
+ ///
+ ///
+ IMethodSymbol MakeGenericMethod(params ITypeSymbol[] typeArguments);
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IModuleSymbol.cs
new file mode 100644
index 0000000000..771d4263c2
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IModuleSymbol.cs
@@ -0,0 +1,226 @@
+using System;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Performs reflection on a module.
+ ///
+ interface IModuleSymbol : ISymbol, ICustomAttributeSymbolProvider
+ {
+
+ ///
+ /// Gets the appropriate for this instance of Module.
+ ///
+ IAssemblySymbol Assembly { get; }
+
+ ///
+ /// Gets a string representing the fully qualified name and path to this module.
+ ///
+ string FullyQualifiedName { get; }
+
+ ///
+ /// Gets a token that identifies the module in metadata.
+ ///
+ int MetadataToken { get; }
+
+ ///
+ /// Gets a universally unique identifier (UUID) that can be used to distinguish between two versions of a module.
+ ///
+ Guid ModuleVersionId { get; }
+
+ ///
+ /// Gets a representing the name of the module with the path removed.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets a string representing the name of the module.
+ ///
+ string ScopeName { get; }
+
+ ///
+ /// Gets a value indicating whether the object is a resource.
+ ///
+ ///
+ bool IsResource();
+
+ ///
+ /// Returns a field having the specified name.
+ ///
+ ///
+ ///
+ IFieldSymbol? GetField(string name);
+
+ ///
+ /// Returns a field having the specified name and binding attributes.
+ ///
+ ///
+ ///
+ ///
+ IFieldSymbol? GetField(string name, BindingFlags bindingAttr);
+
+ ///
+ /// Returns the global fields defined on the module that match the specified binding flags.
+ ///
+ ///
+ ///
+ IFieldSymbol[] GetFields(BindingFlags bindingFlags);
+
+ ///
+ /// Returns the global fields defined on the module.
+ ///
+ ///
+ IFieldSymbol[] GetFields();
+
+ ///
+ /// Returns a method having the specified name.
+ ///
+ ///
+ ///
+ IMethodSymbol? GetMethod(string name);
+
+ ///
+ /// Returns a method having the specified name and parameter types.
+ ///
+ ///
+ ///
+ ///
+ IMethodSymbol? GetMethod(string name, ITypeSymbol[] types);
+
+ ///
+ /// Returns a method having the specified name, binding information, calling convention, and parameter types and modifiers.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, CallingConventions callConvention, ITypeSymbol[] types, ParameterModifier[]? modifiers);
+
+ ///
+ /// Returns the global methods defined on the module.
+ ///
+ ///
+ IMethodSymbol[] GetMethods();
+
+ ///
+ /// Returns the global methods defined on the module that match the specified binding flags.
+ ///
+ ///
+ ///
+ IMethodSymbol[] GetMethods(BindingFlags bindingFlags);
+
+ ///
+ /// Returns the specified type, performing a case-sensitive search.
+ ///
+ ///
+ ///
+ ITypeSymbol? GetType(string className);
+
+ ///
+ /// Returns the specified type, searching the module with the specified case sensitivity.
+ ///
+ ///
+ ///
+ ///
+ ITypeSymbol? GetType(string className, bool ignoreCase);
+
+ ///
+ /// Returns the specified type, specifying whether to make a case-sensitive search of the module and whether to throw an exception if the type cannot be found.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ITypeSymbol? GetType(string className, bool throwOnError, bool ignoreCase);
+
+ ///
+ /// Returns all the types defined within this module.
+ ///
+ ///
+ ITypeSymbol[] GetTypes();
+
+ ///
+ /// Returns the type identified by the specified metadata token.
+ ///
+ ///
+ ///
+ ITypeSymbol ResolveType(int metadataToken);
+
+ ///
+ /// Returns the type identified by the specified metadata token, in the context defined by the specified generic type parameters.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ITypeSymbol ResolveType(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments);
+
+ ///
+ /// Returns the field identified by a metadata token.
+ ///
+ ///
+ ///
+ IFieldSymbol? ResolveField(int metadataToken);
+
+ ///
+ /// Returns the field identified by the specified metadata token, in the context defined by the specified generic type parameters.
+ ///
+ ///
+ ///
+ ///
+ ///
+ IFieldSymbol? ResolveField(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments);
+
+ ///
+ /// Returns the type or member identified by a metadata token.
+ ///
+ ///
+ ///
+ IMemberSymbol? ResolveMember(int metadataToken);
+
+ ///
+ /// Returns the type or member identified by the specified metadata token, in the context defined by the specified generic type parameters.
+ ///
+ ///
+ ///
+ ///
+ ///
+ IMemberSymbol? ResolveMember(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments);
+
+ ///
+ /// Returns the method or constructor identified by the specified metadata token.
+ ///
+ ///
+ ///
+ IMethodBaseSymbol? ResolveMethod(int metadataToken);
+
+ ///
+ /// Returns the method or constructor identified by the specified metadata token, in the context defined by the specified generic type parameters.
+ ///
+ ///
+ ///
+ ///
+ ///
+ IMethodBaseSymbol? ResolveMethod(int metadataToken, ITypeSymbol[]? genericTypeArguments, ITypeSymbol[]? genericMethodArguments);
+
+ ///
+ /// Returns the signature blob identified by a metadata token.
+ ///
+ ///
+ ///
+ byte[] ResolveSignature(int metadataToken);
+
+ ///
+ /// Returns the string identified by the specified metadata token.
+ ///
+ ///
+ ///
+ string ResolveString(int metadataToken);
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs
new file mode 100644
index 0000000000..033015ae7f
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IParameterSymbol.cs
@@ -0,0 +1,79 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Discovers the attributes of a parameter and provides access to parameter metadata.
+ ///
+ interface IParameterSymbol : ISymbol, ICustomAttributeSymbolProvider
+ {
+
+ ///
+ /// Gets the attributes for this parameter.
+ ///
+ ParameterAttributes Attributes { get; }
+
+ ///
+ /// Gets a value indicating the member in which the parameter is implemented.
+ ///
+ IMemberSymbol Member { get; }
+
+ ///
+ /// Gets the Type of this parameter.
+ ///
+ ITypeSymbol ParameterType { get; }
+
+ ///
+ /// Gets the name of the parameter.
+ ///
+ string? Name { get; }
+
+ ///
+ /// Gets the zero-based position of the parameter in the formal parameter list.
+ ///
+ int Position { get; }
+
+ ///
+ /// Gets a value that indicates whether this parameter has a default value.
+ ///
+ bool HasDefaultValue { get; }
+
+ ///
+ /// Gets a value indicating the default value if the parameter has a default value.
+ ///
+ object? DefaultValue { get; }
+
+ ///
+ /// Gets a value indicating whether this is an input parameter.
+ ///
+ bool IsIn { get; }
+
+ ///
+ /// Gets a value indicating whether this is an output parameter.
+ ///
+ bool IsOut { get; }
+
+ ///
+ /// Gets a value indicating whether this parameter is optional.
+ ///
+ bool IsOptional { get; }
+
+ ///
+ /// Gets a value indicating whether this parameter is a locale identifier (lcid).
+ ///
+ bool IsLcid { get; }
+
+ ///
+ /// Gets a value indicating whether this is a Retval parameter.
+ ///
+ bool IsRetval { get; }
+
+ ///
+ /// Gets a value that identifies this parameter in metadata.
+ ///
+ int MetadataToken { get; }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IPropertySymbol.cs
new file mode 100644
index 0000000000..0b73fbf861
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IPropertySymbol.cs
@@ -0,0 +1,118 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Discovers the attributes of a property and provides access to property metadata.
+ ///
+ interface IPropertySymbol : IMemberSymbol
+ {
+
+ ///
+ /// Gets the attributes for this property.
+ ///
+ PropertyAttributes Attributes { get; }
+
+ ///
+ /// Gets the type of this property.
+ ///
+ ITypeSymbol PropertyType { get; }
+
+ ///
+ /// Gets a value indicating whether the property can be read.
+ ///
+ bool CanRead { get; }
+
+ ///
+ /// Gets a value indicating whether the property can be written to.
+ ///
+ bool CanWrite { get; }
+
+ ///
+ /// Gets a value indicating whether the property is the special name.
+ ///
+ bool IsSpecialName { get; }
+
+ ///
+ /// Returns a literal value associated with the property by a compiler.
+ ///
+ ///
+ object? GetRawConstantValue();
+
+ ///
+ /// Gets the get accessor for this property.
+ ///
+ IMethodSymbol? GetMethod { get; }
+
+ ///
+ /// Gets the set accessor for this property.
+ ///
+ IMethodSymbol? SetMethod { get; }
+
+ ///
+ /// Returns an array whose elements reflect the public get and set accessors of the property reflected by the current instance.
+ ///
+ ///
+ IMethodSymbol[] GetAccessors();
+
+ ///
+ /// Returns an array whose elements reflect the public and, if specified, non-public get and set accessors of the property reflected by the current instance.
+ ///
+ ///
+ ///
+ IMethodSymbol[] GetAccessors(bool nonPublic);
+
+ ///
+ /// Returns the public get accessor for this property.
+ ///
+ ///
+ IMethodSymbol? GetGetMethod();
+
+ ///
+ /// When overridden in a derived class, returns the public or non-public get accessor for this property.
+ ///
+ ///
+ ///
+ IMethodSymbol? GetGetMethod(bool nonPublic);
+
+ ///
+ /// Returns the public set accessor for this property.
+ ///
+ ///
+ IMethodSymbol? GetSetMethod();
+
+ ///
+ /// When overridden in a derived class, returns the set accessor for this property.
+ ///
+ ///
+ ///
+ IMethodSymbol? GetSetMethod(bool nonPublic);
+
+ ///
+ /// When overridden in a derived class, returns an array of all the index parameters for the property.
+ ///
+ ///
+ IParameterSymbol[] GetIndexParameters();
+
+ ///
+ /// Gets the modified type of this property object.
+ ///
+ ///
+ ITypeSymbol GetModifiedPropertyType();
+
+ ///
+ /// Returns an array of types representing the optional custom modifiers of the property.
+ ///
+ ///
+ ITypeSymbol[] GetOptionalCustomModifiers();
+
+ ///
+ /// Returns an array of types representing the required custom modifiers of the property.
+ ///
+ ///
+ ITypeSymbol[] GetRequiredCustomModifiers();
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/ISymbol.cs b/src/IKVM.CoreLib/Symbols/ISymbol.cs
new file mode 100644
index 0000000000..91abe16390
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/ISymbol.cs
@@ -0,0 +1,17 @@
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Provides common properties and methods for managed symbols.
+ ///
+ interface ISymbol
+ {
+
+ ///
+ /// Returns true if the symbol is missing.
+ ///
+ bool IsMissing { get; }
+
+ }
+
+}
diff --git a/src/IKVM.Runtime/IManagedTypeResolver.cs b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs
similarity index 62%
rename from src/IKVM.Runtime/IManagedTypeResolver.cs
rename to src/IKVM.CoreLib/Symbols/ISymbolResolver.cs
index 1829ccb7bb..5a4815f8d0 100644
--- a/src/IKVM.Runtime/IManagedTypeResolver.cs
+++ b/src/IKVM.CoreLib/Symbols/ISymbolResolver.cs
@@ -1,20 +1,10 @@
-using System;
-
-#if IMPORTER || EXPORTER
-using IKVM.Reflection;
-
-using Type = IKVM.Reflection.Type;
-#else
-using System.Reflection;
-#endif
-
-namespace IKVM.Runtime
+namespace IKVM.CoreLib.Symbols
{
///
- /// Provides an interface to resolve a managed type.
+ /// Provides an interface to resolve a maaged type symbols.
///
- public interface IManagedTypeResolver
+ interface ISymbolResolver
{
///
@@ -22,27 +12,27 @@ public interface IManagedTypeResolver
///
///
///
- Type ResolveRuntimeType(string typeName);
+ ITypeSymbol? ResolveRuntimeType(string typeName);
///
/// Resolves the named assembly from any reference source.
///
///
///
- Assembly ResolveAssembly(string assemblyName);
+ IAssemblySymbol? ResolveAssembly(string assemblyName);
///
/// Resolves the named type from any reference source.
///
///
///
- Type ResolveCoreType(string typeName);
+ ITypeSymbol? ResolveCoreType(string typeName);
///
/// Resolves the known Java base assembly.
///
///
- Assembly ResolveBaseAssembly();
+ IAssemblySymbol? ResolveBaseAssembly();
}
diff --git a/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs
new file mode 100644
index 0000000000..377a82aa6f
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/ITypeSymbol.cs
@@ -0,0 +1,597 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ ///
+ /// Represents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types.
+ ///
+ interface ITypeSymbol : IMemberSymbol
+ {
+
+ ///
+ /// Gets the attributes associated with the .
+ ///
+ TypeAttributes Attributes { get; }
+
+ ///
+ /// Gets the in which the type is declared. For generic types, gets the in which the generic type is defined.
+ ///
+ IAssemblySymbol Assembly { get; }
+
+ ///
+ /// Gets a that represents the declaring method, if the current represents a type parameter of a generic method.
+ ///
+ IMethodBaseSymbol? DeclaringMethod { get; }
+
+ ///
+ /// Gets the assembly-qualified name of the type, which includes the name of the assembly from which this object was loaded.
+ ///
+ string? AssemblyQualifiedName { get; }
+
+ ///
+ /// Gets the fully qualified name of the type, including its namespace but not its assembly.
+ ///
+ string? FullName { get; }
+
+ ///
+ /// Gets the namespace of the .
+ ///
+ string? Namespace { get; }
+
+ ///
+ /// Gets the type from which the current directly inherits.
+ ///
+ ITypeSymbol? BaseType { get; }
+
+ ///
+ /// Gets a value indicating whether the current object has type parameters that have not been replaced by specific types.
+ ///
+ bool ContainsGenericParameters { get; }
+
+ ///
+ /// Gets a combination of flags that describe the covariance and special constraints of the current generic type parameter.
+ ///
+ GenericParameterAttributes GenericParameterAttributes { get; }
+
+ ///
+ /// Gets the position of the type parameter in the type parameter list of the generic type or method that declared the parameter, when the object represents a type parameter of a generic type or a generic method.
+ ///
+ int GenericParameterPosition { get; }
+
+ ///
+ /// Gets an array of the generic type arguments for this type.
+ ///
+ ITypeSymbol[] GenericTypeArguments { get; }
+
+ ///
+ /// Gets a value that indicates whether this object represents a constructed generic type. You can create instances of a constructed generic type.
+ ///
+ bool IsConstructedGenericType { 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 current type is a generic type.
+ ///
+ bool IsGenericType { get; }
+
+ ///
+ /// Gets a value indicating whether the fields of the current type are laid out automatically by the common language runtime.
+ ///
+ bool IsAutoLayout { get; }
+
+ ///
+ /// Gets a value indicating whether the fields of the current type are laid out at explicitly specified offsets.
+ ///
+ bool IsExplicitLayout { get; }
+
+ ///
+ /// Gets a value indicating whether the fields of the current type are laid out sequentially, in the order that they were defined or emitted to the metadata.
+ ///
+ bool IsLayoutSequential { get; }
+
+ ///
+ /// Gets a value indicating whether the current encompasses or refers to another type; that is, whether the current is an array, a pointer, or is passed by reference.
+ ///
+ bool HasElementType { get; }
+
+ ///
+ /// Gets a value indicating whether the is a class or a delegate; that is, not a value type or interface.
+ ///
+ bool IsClass { get; }
+
+ ///
+ /// Gets a value indicating whether the is a value type.
+ ///
+ bool IsValueType { get; }
+
+ ///
+ /// Gets a value indicating whether the is an interface; that is, not a class or a value type.
+ ///
+ bool IsInterface { get; }
+
+ ///
+ /// Gets a value indicating whether the is one of the primitive types.
+ ///
+ bool IsPrimitive { get; }
+
+ ///
+ /// Gets a value that indicates whether the type is an array.
+ ///
+ bool IsArray { get; }
+
+ ///
+ /// Gets a value indicating whether the current represents an enumeration.
+ ///
+ bool IsEnum { get; }
+
+ ///
+ /// Gets a value indicating whether the is a pointer.
+ ///
+ bool IsPointer { get; }
+
+ ///
+ /// Gets a value indicating whether the is passed by reference.
+ ///
+ bool IsByRef { get; }
+
+ ///
+ /// Gets a value indicating whether the is abstract and must be overridden.
+ ///
+ bool IsAbstract { get; }
+
+ ///
+ /// Gets a value indicating whether the is declared sealed.
+ ///
+ bool IsSealed { get; }
+
+ ///
+ /// Gets a value indicating whether the can be accessed by code outside the assembly.
+ ///
+ bool IsVisible { get; }
+
+ ///
+ /// Gets a value indicating whether the is declared public.
+ ///
+ bool IsPublic { get; }
+
+ ///
+ /// Gets a value indicating whether the is not declared public.
+ ///
+ bool IsNotPublic { get; }
+
+ ///
+ /// Gets a value indicating whether the current object represents a type whose definition is nested inside the definition of another type.
+ ///
+ bool IsNested { get; }
+
+ ///
+ /// Gets a value indicating whether the is nested and visible only within its own assembly.
+ ///
+ bool IsNestedAssembly { get; }
+
+ ///
+ /// Gets a value indicating whether the is nested and visible only to classes that belong to both its own family and its own assembly.
+ ///
+ bool IsNestedFamANDAssem { get; }
+
+ ///
+ /// Gets a value indicating whether the is nested and visible only within its own family.
+ ///
+ bool IsNestedFamily { get; }
+
+ ///
+ /// Gets a value indicating whether the is nested and visible only to classes that belong to either its own family or to its own assembly.
+ ///
+ bool IsNestedFamORAssem { get; }
+
+ ///
+ /// Gets a value indicating whether the is nested and declared private.
+ ///
+ bool IsNestedPrivate { get; }
+
+ ///
+ /// Gets a value indicating whether a class is nested and declared public.
+ ///
+ bool IsNestedPublic { get; }
+
+ ///
+ /// Gets a value indicating whether the is binary serializable.
+ ///
+ bool IsSerializable { get; }
+
+ ///
+ /// Gets the initializer for the type.
+ ///
+ IConstructorSymbol? TypeInitializer { get; }
+
+ ///
+ /// Gets the number of dimensions in an array.
+ ///
+ ///
+ int GetArrayRank();
+
+ ///
+ /// Searches for the members defined for the current whose DefaultMemberAttribute is set.
+ ///
+ ///
+ IMemberSymbol[] GetDefaultMembers();
+
+ ///
+ /// When overridden in a derived class, returns the of the object encompassed or referred to by the current array, pointer or reference type.
+ ///
+ ///
+ ITypeSymbol? GetElementType();
+
+ ///
+ /// Returns the name of the constant that has the specified value, for the current enumeration type.
+ ///
+ ///
+ ///
+ string? GetEnumName(object value);
+
+ ///
+ /// Returns the names of the members of the current enumeration type.
+ ///
+ ///
+ string[] GetEnumNames();
+
+ ///
+ /// Returns the underlying type of the current enumeration type.
+ ///
+ ///
+ ITypeSymbol GetEnumUnderlyingType();
+
+ ///
+ /// 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();
+
+ ///
+ /// Returns an array of objects that represent the constraints on the current generic type parameter.
+ ///
+ ///
+ ITypeSymbol[] GetGenericParameterConstraints();
+
+ ///
+ /// Returns a object that represents a generic type definition from which the current generic type can be constructed.
+ ///
+ ///
+ ITypeSymbol GetGenericTypeDefinition();
+
+ ///
+ /// Searches for the interface with the specified name.
+ ///
+ ///
+ ///
+ ITypeSymbol? GetInterface(string name);
+
+ ///
+ /// When overridden in a derived class, searches for the specified interface, specifying whether to do a case-insensitive search for the interface name.
+ ///
+ ///
+ ///
+ ///
+ ITypeSymbol? GetInterface(string name, bool ignoreCase);
+
+ ///
+ /// When overridden in a derived class, gets all the interfaces implemented or inherited by the current .
+ ///
+ ///
+ ITypeSymbol[] GetInterfaces();
+
+ ///
+ /// Returns an interface mapping for the specified interface type.
+ ///
+ ///
+ ///
+ InterfaceMapping GetInterfaceMap(ITypeSymbol interfaceType);
+
+ ///
+ /// Searches for the public members with the specified name.
+ ///
+ ///
+ ///
+ 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);
+
+ ///
+ /// Searches for a public instance constructor whose parameters match the types in the specified array.
+ ///
+ ///
+ ///
+ IConstructorSymbol? GetConstructor(ITypeSymbol[] types);
+
+ ///
+ /// Searches for a constructor whose parameters match the specified argument types, using the specified binding constraints.
+ ///
+ ///
+ ///
+ ///
+ IConstructorSymbol? GetConstructor(BindingFlags bindingAttr, ITypeSymbol[] types);
+
+ ///
+ /// Returns all the public constructors defined for the current .
+ ///
+ ///
+ IConstructorSymbol[] GetConstructors();
+
+ ///
+ /// When overridden in a derived class, searches for the constructors defined for the current , using the specified BindingFlags.
+ ///
+ ///
+ ///
+ IConstructorSymbol[] GetConstructors(BindingFlags bindingAttr);
+
+ ///
+ /// Searches for the public field with the specified name.
+ ///
+ ///
+ ///
+ IFieldSymbol? GetField(string name);
+
+ ///
+ /// Searches for the specified field, using the specified binding constraints.
+ ///
+ ///
+ ///
+ ///
+ IFieldSymbol? GetField(string name, BindingFlags bindingAttr);
+
+ ///
+ /// Returns all the public fields of the current .
+ ///
+ ///
+ IFieldSymbol[] GetFields();
+
+ ///
+ /// When overridden in a derived class, searches for the fields defined for the current , using the specified binding constraints.
+ ///
+ ///
+ ///
+ IFieldSymbol[] GetFields(BindingFlags bindingAttr);
+
+ ///
+ /// Searches for the public method with the specified name.
+ ///
+ ///
+ ///
+ IMethodSymbol? GetMethod(string name);
+
+ ///
+ /// Searches for the specified public method whose parameters match the specified argument types.
+ ///
+ ///
+ ///
+ ///
+ IMethodSymbol? GetMethod(string name, ITypeSymbol[] types);
+
+ ///
+ /// Searches for the specified method, using the specified binding constraints.
+ ///
+ ///
+ ///
+ ///
+ IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr);
+
+ ///
+ /// 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);
+
+ ///
+ /// Returns all the public methods of the current .
+ ///
+ ///
+ IMethodSymbol[] GetMethods();
+
+ ///
+ /// When overridden in a derived class, searches for the methods defined for the current , using the specified binding constraints.
+ ///
+ ///
+ ///
+ IMethodSymbol[] GetMethods(BindingFlags bindingAttr);
+
+ ///
+ /// Searches for the public property with the specified name.
+ ///
+ ///
+ ///
+ IPropertySymbol? GetProperty(string name);
+
+ ///
+ /// Searches for the specified property, using the specified binding constraints.
+ ///
+ ///
+ ///
+ ///
+ IPropertySymbol? GetProperty(string name, BindingFlags bindingAttr);
+
+ ///
+ /// Searches for the specified public property whose parameters match the specified argument types.
+ ///
+ ///
+ ///
+ ///
+ IPropertySymbol? GetProperty(string name, ITypeSymbol[] types);
+
+ ///
+ /// Searches for the specified public property whose parameters match the specified argument types.
+ ///
+ ///
+ ///
+ ///
+ ///
+ IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType, ITypeSymbol[] types);
+
+ ///
+ /// Searches for the public property with the specified name and return type.
+ ///
+ ///
+ ///
+ ///
+ IPropertySymbol? GetProperty(string name, ITypeSymbol? returnType);
+
+ ///
+ /// Returns all the public properties of the current .
+ ///
+ ///
+ IPropertySymbol[] GetProperties();
+
+ ///
+ /// When overridden in a derived class, searches for the properties of the current , using the specified binding constraints.
+ ///
+ ///
+ ///
+ IPropertySymbol[] GetProperties(BindingFlags bindingAttr);
+
+ ///
+ /// Returns the EventInfo 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.
+ ///
+ ///
+ ///
+ ///
+ IEventSymbol? GetEvent(string name, BindingFlags bindingAttr);
+
+ ///
+ /// Returns all the public events that are declared or inherited by the current .
+ ///
+ ///
+ IEventSymbol[] 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);
+
+ ///
+ /// Searches for the public nested type with the specified name.
+ ///
+ ///
+ ///
+ ITypeSymbol? GetNestedType(string name);
+
+ ///
+ /// When overridden in a derived class, searches for the specified nested type, using the specified binding constraints.
+ ///
+ ///
+ ///
+ ///
+ ITypeSymbol? GetNestedType(string name, BindingFlags bindingAttr);
+
+ ///
+ /// Returns the public types nested in the current .
+ ///
+ ///
+ ITypeSymbol[] GetNestedTypes();
+
+ ///
+ /// When overridden in a derived class, searches for the types nested in the current , using the specified binding constraints.
+ ///
+ ///
+ ///
+ ITypeSymbol[] GetNestedTypes(BindingFlags bindingAttr);
+
+ ///
+ /// Determines whether an instance of a specified type c can be assigned to a variable of the current type.
+ ///
+ ///
+ ///
+ bool IsAssignableFrom(ITypeSymbol? c);
+
+ ///
+ /// Determines whether the current derives from the specified .
+ ///
+ ///
+ ///
+ bool IsSubclassOf(ITypeSymbol c);
+
+ ///
+ /// Returns a value that indicates whether the specified value exists in the current enumeration type.
+ ///
+ ///
+ ///
+ bool IsEnumDefined(object value);
+
+ ///
+ /// Returns a object representing a one-dimensional array of the current type, with a lower bound of zero.
+ ///
+ ///
+ ITypeSymbol MakeArrayType();
+
+ ///
+ /// Returns a object representing an array of the current type, with the specified number of dimensions.
+ ///
+ ///
+ ///
+ ITypeSymbol MakeArrayType(int rank);
+
+ ///
+ /// Substitutes the elements of an array of types for the type parameters of the current generic type definition and returns a object representing the resulting constructed type.
+ ///
+ ///
+ ///
+ ITypeSymbol MakeGenericType(params ITypeSymbol[] typeArguments);
+
+ ///
+ /// Returns a object that represents a pointer to the current type.
+ ///
+ ///
+ ITypeSymbol MakePointerType();
+
+ ///
+ /// Returns a object that represents the current type when passed as a ref parameter (ByRef parameter in Visual Basic).
+ ///
+ ///
+ ITypeSymbol MakeByRefType();
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs
new file mode 100644
index 0000000000..12920dd971
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionAssemblySymbol.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+using Assembly = IKVM.Reflection.Assembly;
+using AssemblyName = IKVM.Reflection.AssemblyName;
+using Module = IKVM.Reflection.Module;
+using Type = IKVM.Reflection.Type;
+
+namespace IKVM.CoreLib.Symbols.IkvmReflection
+{
+
+ class IkvmReflectionAssemblySymbol : IkvmReflectionSymbol, IAssemblySymbol
+ {
+
+ readonly Assembly _assembly;
+ readonly ConditionalWeakTable _modules = new();
+
+ System.Reflection.AssemblyName? _assemblyName;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ public IkvmReflectionAssemblySymbol(IkvmReflectionSymbolContext context, Assembly assembly) :
+ base(context)
+ {
+ _assembly = assembly ?? throw new ArgumentNullException(nameof(assembly));
+ }
+
+ ///
+ /// Gets or creates the cached for the module.
+ ///
+ ///
+ ///
+ ///
+ internal IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module)
+ {
+ Debug.Assert(module.Assembly == _assembly);
+ return _modules.GetValue(module, _ => new IkvmReflectionModuleSymbol(Context, _));
+ }
+
+ 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 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));
+ }
+
+ 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());
+ }
+
+ public System.Reflection.AssemblyName GetName(bool copiedName)
+ {
+ return ToName(_assembly.GetName());
+ }
+
+ 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]);
+
+ 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()
+ {
+ return ResolveCustomAttributes(_assembly.GetCustomAttributesData());
+ }
+
+ public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_assembly.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false));
+ }
+
+ public bool IsDefined(ITypeSymbol attributeType)
+ {
+ return _assembly.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false);
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs
new file mode 100644
index 0000000000..4a312beb3f
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionConstructorSymbol.cs
@@ -0,0 +1,26 @@
+using ConstructorInfo = IKVM.Reflection.ConstructorInfo;
+
+namespace IKVM.CoreLib.Symbols.IkvmReflection
+{
+
+ class IkvmReflectionConstructorSymbol : IkvmReflectionMethodBaseSymbol, IConstructorSymbol
+ {
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionConstructorSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, IkvmReflectionTypeSymbol type, ConstructorInfo ctor) :
+ base(context, module, type, ctor)
+ {
+
+ }
+
+ internal new ConstructorInfo ReflectionObject => (ConstructorInfo)base.ReflectionObject;
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs
new file mode 100644
index 0000000000..6ba509c128
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionEventSymbol.cs
@@ -0,0 +1,79 @@
+using System;
+
+using EventInfo = IKVM.Reflection.EventInfo;
+
+namespace IKVM.CoreLib.Symbols.IkvmReflection
+{
+
+ class IkvmReflectionEventSymbol : IkvmReflectionMemberSymbol, IEventSymbol
+ {
+
+ readonly EventInfo _event;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionEventSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, EventInfo @event) :
+ base(context, type.ContainingModule, type, @event)
+ {
+ _event = @event ?? throw new ArgumentNullException(nameof(@event));
+ }
+
+ public IMethodSymbol? AddMethod => _event.AddMethod is { } m ? ResolveMethodSymbol(m) : null;
+
+ 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? RemoveMethod => _event.RemoveMethod 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()
+ {
+ return ResolveMethodSymbols(_event.GetOtherMethods());
+ }
+
+ public IMethodSymbol[] GetOtherMethods(bool nonPublic)
+ {
+ return ResolveMethodSymbols(_event.GetOtherMethods(nonPublic));
+ }
+
+ 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)
+ {
+ return _event.GetRemoveMethod(nonPublic) is { } m ? ResolveMethodSymbol(m) : null;
+ }
+
+ public IMethodSymbol? GetRemoveMethod()
+ {
+ return _event.GetRemoveMethod() is { } m ? ResolveMethodSymbol(m) : null;
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs
new file mode 100644
index 0000000000..2696069963
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionFieldSymbol.cs
@@ -0,0 +1,74 @@
+using System;
+
+using FieldInfo = IKVM.Reflection.FieldInfo;
+
+namespace IKVM.CoreLib.Symbols.IkvmReflection
+{
+
+ class IkvmReflectionFieldSymbol : IkvmReflectionMemberSymbol, IFieldSymbol
+ {
+
+ readonly FieldInfo _field;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionFieldSymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, FieldInfo field) :
+ base(context, type.ContainingModule, type, field)
+ {
+ _field = field ?? throw new ArgumentNullException(nameof(field));
+ }
+
+ 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 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 object? GetRawConstantValue()
+ {
+ return _field.GetRawConstantValue();
+ }
+
+ public ITypeSymbol[] GetRequiredCustomModifiers()
+ {
+ return ResolveTypeSymbols(_field.GetRequiredCustomModifiers());
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs
new file mode 100644
index 0000000000..e32966d91f
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMemberSymbol.cs
@@ -0,0 +1,164 @@
+using System;
+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
+{
+
+ abstract class IkvmReflectionMemberSymbol : IkvmReflectionSymbol, IMemberSymbol
+ {
+
+ readonly IkvmReflectionModuleSymbol _module;
+ readonly IkvmReflectionTypeSymbol? _type;
+ readonly MemberInfo _member;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionMemberSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, IkvmReflectionTypeSymbol? type, MemberInfo member) :
+ base(context)
+ {
+ _module = module ?? throw new ArgumentNullException(nameof(module));
+ _type = type;
+ _member = member ?? throw new ArgumentNullException(nameof(member));
+ }
+
+ ///
+ /// Resolves the symbol for the specified type.
+ ///
+ ///
+ ///
+ protected internal override IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type)
+ {
+ if (_type != null && type == _type.ReflectionObject)
+ return _type;
+ else if (type.Module == _member.Module)
+ return _module.GetOrCreateTypeSymbol(type);
+ else
+ return base.ResolveTypeSymbol(type);
+ }
+
+ ///
+ /// Resolves the symbol for the specified constructor.
+ ///
+ ///
+ ///
+ 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);
+ else
+ return base.ResolveConstructorSymbol(ctor);
+ }
+
+ ///
+ /// Resolves the symbol for the specified method.
+ ///
+ ///
+ ///
+ 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);
+ else
+ return base.ResolveMethodSymbol(method);
+ }
+
+ ///
+ /// Resolves the symbol for the specified field.
+ ///
+ ///
+ ///
+ 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);
+ else
+ return base.ResolveFieldSymbol(field);
+ }
+
+
+ ///
+ /// Resolves the symbol for the specified field.
+ ///
+ ///
+ ///
+ 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);
+ else
+ return base.ResolvePropertySymbol(property);
+ }
+
+ ///
+ /// Resolves the symbol for the specified event.
+ ///
+ ///
+ ///
+ 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);
+ else
+ 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()
+ {
+ return ResolveCustomAttributes(_member.GetCustomAttributesData());
+ }
+
+ public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_member.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray();
+ }
+
+ public virtual bool IsDefined(ITypeSymbol attributeType)
+ {
+ return _member.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs
new file mode 100644
index 0000000000..644d3f05c1
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodBaseSymbol.cs
@@ -0,0 +1,129 @@
+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
+{
+
+ abstract class IkvmReflectionMethodBaseSymbol : IkvmReflectionMemberSymbol, IMethodBaseSymbol
+ {
+
+ readonly MethodBase _method;
+
+ ParameterInfo[]? _parametersSource;
+ IkvmReflectionParameterSymbol?[]? _parameters;
+ IkvmReflectionParameterSymbol? _returnParameter;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionMethodBaseSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, IkvmReflectionTypeSymbol? type, MethodBase method) :
+ base(context, module, type, method)
+ {
+ _method = method ?? throw new ArgumentNullException(nameof(method));
+ }
+
+ ///
+ /// 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 == _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;
+ }
+
+ 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 ITypeSymbol[] GetGenericArguments()
+ {
+ return ResolveTypeSymbols(_method.GetGenericArguments());
+ }
+
+ public System.Reflection.MethodImplAttributes GetMethodImplementationFlags()
+ {
+ return (System.Reflection.MethodImplAttributes)_method.GetMethodImplementationFlags();
+ }
+
+ public IParameterSymbol[] GetParameters()
+ {
+ return ResolveParameterSymbols(_method.GetParameters());
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs
new file mode 100644
index 0000000000..51fbc6a326
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionMethodSymbol.cs
@@ -0,0 +1,131 @@
+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
+{
+
+ 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)
+ {
+ _method = method ?? throw new ArgumentNullException(nameof(method));
+ }
+
+ ///
+ /// Gets or creates the cached for the generic parameter type.
+ ///
+ ///
+ ///
+ ///
+ internal IkvmReflectionTypeSymbol GetOrCreateGenericParameterSymbol(Type genericParameterType)
+ {
+ 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.
+ ///
+ ///
+ ///
+ ///
+ 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;
+
+ public IParameterSymbol ReturnParameter => ResolveParameterSymbol(_method.ReturnParameter);
+
+ public ITypeSymbol ReturnType => ResolveTypeSymbol(_method.ReturnType);
+
+ public ICustomAttributeSymbolProvider 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)));
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs
new file mode 100644
index 0000000000..9c30b305a4
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionModuleSymbol.cs
@@ -0,0 +1,357 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection.Metadata.Ecma335;
+using System.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;
+ }
+
+ readonly Module _module;
+
+ Type[]? _typesSource;
+ int _typesBaseRow;
+ IkvmReflectionTypeSymbol?[]? _types;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionModuleSymbol(IkvmReflectionSymbolContext context, Module module) :
+ base(context)
+ {
+ _module = module ?? throw new ArgumentNullException(nameof(module));
+ }
+
+ ///
+ /// 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 not a definition, but is substituted
+ if (IsTypeDefinition(type) == false)
+ return GetOrCreateTypeSymbolForSpecification(type);
+
+ // look up handle and row
+ var hnd = MetadataTokens.TypeDefinitionHandle(type.MetadataToken);
+ var row = MetadataTokens.GetRowNumber(hnd);
+
+ // initialize source table
+ if (_typesSource == null)
+ {
+ _typesSource = _module.GetTypes().OrderBy(i => i.MetadataToken).ToArray();
+ _typesBaseRow = _typesSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_typesSource[0].MetadataToken)) : 0;
+ }
+
+ // initialize cache table
+ _types ??= new IkvmReflectionTypeSymbol?[_typesSource.Length];
+
+ // index of current record is specified row - base
+ var idx = row - _typesBaseRow;
+ if (idx < 0)
+ throw new Exception();
+
+ 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
+ ///
+ ///
+ ///
+ 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 = GetOrCreateTypeSymbol(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 definitionType = type.GetGenericTypeDefinition();
+ var definitionTypeSymbol = GetOrCreateTypeSymbol(definitionType);
+ 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);
+ 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);
+ return declaringMethod.GetOrCreateGenericParameterSymbol(type);
+ }
+
+ 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 override bool IsMissing => _module.__IsMissing;
+
+ ///
+ 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, UnpackTypeSymbols(types)) 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;
+ }
+
+ ///
+ 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)
+ {
+ 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;
+ }
+
+ ///
+ public IMemberSymbol? ResolveMember(int metadataToken)
+ {
+ return _module.ResolveMember(metadataToken) is { } m ? ResolveMemberSymbol(m) : null;
+ }
+
+ ///
+ 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;
+ }
+
+ ///
+ 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;
+ }
+
+ ///
+ 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)
+ {
+ var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null;
+ var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null;
+ return ResolveTypeSymbol(_module.ResolveType(metadataToken, _genericTypeArguments, _genericMethodArguments));
+ }
+
+ ///
+ public CustomAttributeSymbol[] GetCustomAttributes()
+ {
+ return ResolveCustomAttributes(_module.GetCustomAttributesData());
+ }
+
+ ///
+ public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_module.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false));
+ }
+
+ ///
+ public bool IsDefined(ITypeSymbol attributeType)
+ {
+ 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
new file mode 100644
index 0000000000..c63d92cad6
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionParameterSymbol.cs
@@ -0,0 +1,72 @@
+using System;
+
+using ParameterInfo = IKVM.Reflection.ParameterInfo;
+
+namespace IKVM.CoreLib.Symbols.IkvmReflection
+{
+
+ class IkvmReflectionParameterSymbol : IkvmReflectionSymbol, IParameterSymbol
+ {
+
+ readonly ParameterInfo _parameter;
+ readonly IkvmReflectionMethodBaseSymbol _method;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionParameterSymbol(IkvmReflectionSymbolContext context, IkvmReflectionMethodBaseSymbol method, ParameterInfo parameter) :
+ base(context)
+ {
+ _method = method ?? throw new ArgumentNullException(nameof(method));
+ _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter));
+ }
+
+ internal IkvmReflectionMethodBaseSymbol ContainingMethod => _method;
+
+ 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()
+ {
+ return ResolveCustomAttributes(_parameter.GetCustomAttributesData());
+ }
+
+ public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_parameter.__GetCustomAttributes(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false));
+ }
+
+ public bool IsDefined(ITypeSymbol attributeType)
+ {
+ return _parameter.IsDefined(((IkvmReflectionTypeSymbol)attributeType).ReflectionObject, false);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs
new file mode 100644
index 0000000000..f16d0b9a08
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionPropertySymbol.cs
@@ -0,0 +1,117 @@
+using System;
+
+using IKVM.Reflection;
+
+using PropertyInfo = IKVM.Reflection.PropertyInfo;
+
+namespace IKVM.CoreLib.Symbols.IkvmReflection
+{
+
+ class IkvmReflectionPropertySymbol : IkvmReflectionMemberSymbol, IPropertySymbol
+ {
+
+ readonly PropertyInfo _property;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionPropertySymbol(IkvmReflectionSymbolContext context, IkvmReflectionTypeSymbol type, PropertyInfo property) :
+ base(context, type.ContainingModule, type, property)
+ {
+ _property = property ?? throw new ArgumentNullException(nameof(property));
+ }
+
+ public new PropertyInfo ReflectionObject => (PropertyInfo)base.ReflectionObject;
+
+ ///
+ public System.Reflection.PropertyAttributes Attributes => (System.Reflection.PropertyAttributes)_property.Attributes;
+
+ ///
+ public ITypeSymbol PropertyType => ResolveTypeSymbol(_property.PropertyType);
+
+ ///
+ public bool CanRead => _property.CanRead;
+
+ ///
+ public bool CanWrite => _property.CanWrite;
+
+ ///
+ public bool IsSpecialName => _property.IsSpecialName;
+
+ ///
+ 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 IParameterSymbol[] GetIndexParameters()
+ {
+ return ResolveParameterSymbols(_property.GetIndexParameters());
+ }
+
+ ///
+ public ITypeSymbol GetModifiedPropertyType()
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ public IMethodSymbol[] GetAccessors()
+ {
+ return ResolveMethodSymbols(_property.GetAccessors());
+ }
+
+ ///
+ public IMethodSymbol[] GetAccessors(bool nonPublic)
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ 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[] GetOptionalCustomModifiers()
+ {
+ return ResolveTypeSymbols(_property.GetOptionalCustomModifiers());
+ }
+
+ ///
+ public ITypeSymbol[] GetRequiredCustomModifiers()
+ {
+ return ResolveTypeSymbols(_property.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 0000000000..e1bf81bf8c
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbol.cs
@@ -0,0 +1,427 @@
+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
+{
+
+ 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 virtual bool IsMissing => 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);
+ }
+
+ ///
+ /// 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.
+ ///
+ ///
+ ///
+ 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;
+ }
+
+ ///
+ /// 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.
+ ///
+ ///
+ ///
+ 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);
+ }
+
+ ///
+ /// 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.
+ ///
+ ///
+ ///
+ 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 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.
+ ///
+ ///
+ ///
+ 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;
+ }
+
+ ///
+ /// Transforms a custom set of custom attribute data records to a symbol record.
+ ///
+ ///
+ ///
+ protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IList attributes)
+ {
+ var a = new CustomAttributeSymbol[attributes.Count];
+ for (int i = 0; i < attributes.Count; i++)
+ a[i] = ResolveCustomAttribute(attributes[i]);
+
+ return a;
+ }
+
+ ///
+ /// Transforms a custom attribute data record to a symbol record.
+ ///
+ ///
+ ///
+ ///
+ protected internal CustomAttributeSymbol ResolveCustomAttribute(CustomAttributeData customAttributeData)
+ {
+ return new CustomAttributeSymbol(
+ 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 CustomAttributeSymbolTypedArgument[args.Count];
+ for (int i = 0; i < args.Count; i++)
+ a[i] = ResolveCustomAttributeTypedArgument(args[i]);
+
+ return a.ToImmutableArray();
+ }
+
+ ///
+ /// Transforms a values into a symbol.
+ ///
+ ///
+ ///
+ CustomAttributeSymbolTypedArgument ResolveCustomAttributeTypedArgument(CustomAttributeTypedArgument arg)
+ {
+ return new CustomAttributeSymbolTypedArgument(ResolveTypeSymbol(arg.ArgumentType), arg.Value);
+ }
+
+ ///
+ /// Transforms a list of values into symbols.
+ ///
+ ///
+ ///
+ ImmutableArray ResolveCustomAttributeNamedArguments(IList args)
+ {
+ var a = new CustomAttributeSymbolNamedArgument[args.Count];
+ for (int i = 0; i < args.Count; i++)
+ a[i] = ResolveCustomAttributeNamedArgument(args[i]);
+
+ return a.ToImmutableArray();
+ }
+
+ ///
+ /// Transforms a values into a symbol.
+ ///
+ ///
+ ///
+ CustomAttributeSymbolNamedArgument ResolveCustomAttributeNamedArgument(CustomAttributeNamedArgument arg)
+ {
+ return new CustomAttributeSymbolNamedArgument(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 0000000000..fcbc6d34d1
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionSymbolContext.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Runtime.CompilerServices;
+
+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 ConditionalWeakTable _assemblies = new();
+
+ ///
+ /// Initializes a new instance.
+ ///
+ public IkvmReflectionSymbolContext()
+ {
+
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public IkvmReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly)
+ {
+ if (assembly is null)
+ throw new ArgumentNullException(nameof(assembly));
+
+ return _assemblies.GetValue(assembly, _ => new IkvmReflectionAssemblySymbol(this, _));
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public IkvmReflectionModuleSymbol GetOrCreateModuleSymbol(Module module)
+ {
+ if (module is null)
+ throw new ArgumentNullException(nameof(module));
+
+ return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ 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 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);
+ }
+
+ ///
+ /// 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);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ 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);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ 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);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ 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);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public IkvmReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event)
+ {
+ if (@event is null)
+ throw new ArgumentNullException(nameof(@event));
+
+ return GetOrCreateAssemblySymbol(@event.Module.Assembly).GetOrCreateModuleSymbol(@event.Module).GetOrCreateTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event);
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs
new file mode 100644
index 0000000000..84c73c8988
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/IkvmReflection/IkvmReflectionTypeSymbol.cs
@@ -0,0 +1,864 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection.Metadata.Ecma335;
+using System.Threading;
+
+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
+{
+
+ 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;
+
+ PropertyInfo[]? _propertiesSource;
+ int _propertiesBaseRow;
+ IkvmReflectionPropertySymbol?[]? _properties;
+
+ EventInfo[]? _eventsSource;
+ int _eventsBaseRow;
+ IkvmReflectionEventSymbol?[]? _events;
+
+ IkvmReflectionTypeSymbol?[]? _asArray;
+ IkvmReflectionTypeSymbol? _asSZArray;
+ IkvmReflectionTypeSymbol? _asPointer;
+ IkvmReflectionTypeSymbol? _asByRef;
+
+ Type[]? _genericParametersSource;
+ IkvmReflectionTypeSymbol?[]? _genericParameters;
+ List<(Type[] Arguments, IkvmReflectionTypeSymbol Symbol)>? _genericTypes;
+ ReaderWriterLockSlim? _genericTypesLock;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public IkvmReflectionTypeSymbol(IkvmReflectionSymbolContext context, IkvmReflectionModuleSymbol module, Type type) :
+ base(context, module, null, 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)
+ {
+ if (genericTypeArguments is null)
+ throw new ArgumentNullException(nameof(genericTypeArguments));
+
+ 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();
+
+ // 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();
+ }
+ }
+
+ ///
+ /// Resolves the symbol for the specified type.
+ ///
+ ///
+ ///
+ protected internal override IkvmReflectionTypeSymbol ResolveTypeSymbol(Type type)
+ {
+ if (type == _type)
+ return this;
+ else
+ 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 .
+ ///
+ 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 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 IsArray => _type.IsArray;
+
+ public bool IsAutoLayout => _type.IsAutoLayout;
+
+ 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 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 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, 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()
+ {
+ return ResolveTypeSymbols(_type.GetInterfaces());
+ }
+
+ 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)
+ throw new NotImplementedException();
+
+ 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)
+ 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;
+ }
+
+ 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;
+
+ 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)
+ 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;
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/InterfaceMapping.cs b/src/IKVM.CoreLib/Symbols/InterfaceMapping.cs
new file mode 100644
index 0000000000..e2208e0e02
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/InterfaceMapping.cs
@@ -0,0 +1,16 @@
+using System.Collections.Immutable;
+
+namespace IKVM.CoreLib.Symbols
+{
+
+ readonly struct InterfaceMapping
+ {
+
+ public readonly ImmutableArray InterfaceMethods;
+ public readonly ITypeSymbol InterfaceType;
+ public readonly ImmutableArray TargetMethods;
+ public readonly ITypeSymbol TargetType;
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs
new file mode 100644
index 0000000000..5165146189
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionAssemblySymbol.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ class ReflectionAssemblySymbol : ReflectionSymbol, IAssemblySymbol
+ {
+
+ readonly Assembly _assembly;
+ readonly ConditionalWeakTable _modules = new();
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ public ReflectionAssemblySymbol(ReflectionSymbolContext 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 ReflectionModuleSymbol GetOrCreateModuleSymbol(Module module)
+ {
+ Debug.Assert(module.Assembly == _assembly);
+ 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()
+ {
+ return ResolveCustomAttributes(_assembly.GetCustomAttributesData());
+ }
+
+ public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_assembly.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray();
+ }
+
+ public bool IsDefined(ITypeSymbol attributeType)
+ {
+ return _assembly.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject);
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs
new file mode 100644
index 0000000000..aba5e173f4
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionConstructorSymbol.cs
@@ -0,0 +1,26 @@
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ class ReflectionConstructorSymbol : ReflectionMethodBaseSymbol, IConstructorSymbol
+ {
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ReflectionConstructorSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, ReflectionTypeSymbol type, ConstructorInfo ctor) :
+ base(context, module, type, ctor)
+ {
+
+ }
+
+ internal new ConstructorInfo ReflectionObject => (ConstructorInfo)base.ReflectionObject;
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs
new file mode 100644
index 0000000000..7c4a37a7b2
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionEventSymbol.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ class ReflectionEventSymbol : ReflectionMemberSymbol, IEventSymbol
+ {
+
+ readonly EventInfo _event;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public ReflectionEventSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, EventInfo @event) :
+ base(context, type.ContainingModule, type, @event)
+ {
+ _event = @event ?? throw new ArgumentNullException(nameof(@event));
+ }
+
+ ///
+ /// Gets the underlying wrapped by this symbol.
+ ///
+ internal new EventInfo ReflectionObject => _event;
+
+ ///
+ public EventAttributes Attributes => _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));
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs
new file mode 100644
index 0000000000..8ba9a0eb66
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionFieldSymbol.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ class ReflectionFieldSymbol : ReflectionMemberSymbol, IFieldSymbol
+ {
+
+ readonly FieldInfo _field;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public ReflectionFieldSymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, FieldInfo field) :
+ base(context, type.ContainingModule, type, field)
+ {
+ _field = field ?? throw new ArgumentNullException(nameof(field));
+ }
+
+ ///
+ /// Gets the underlying wrapped by this symbol.
+ ///
+ internal new FieldInfo ReflectionObject => (FieldInfo)base.ReflectionObject;
+
+ ///
+ public FieldAttributes Attributes => _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();
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs
new file mode 100644
index 0000000000..28e417cab8
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMemberSymbol.cs
@@ -0,0 +1,175 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ ///
+ /// Obtains information about the attributes of a member and provides access to member metadata.
+ ///
+ abstract class ReflectionMemberSymbol : ReflectionSymbol, IMemberSymbol
+ {
+
+ readonly ReflectionModuleSymbol _module;
+ readonly ReflectionTypeSymbol? _type;
+ readonly MemberInfo _member;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ReflectionMemberSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, ReflectionTypeSymbol? type, MemberInfo member) :
+ base(context)
+ {
+ _module = module ?? throw new ArgumentNullException(nameof(module));
+ _type = type;
+ _member = member ?? throw new ArgumentNullException(nameof(member));
+ }
+
+ ///
+ /// Resolves the symbol for the specified type.
+ ///
+ ///
+ ///
+ protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type)
+ {
+ if (_type != null && type == _type.ReflectionObject)
+ return _type;
+ else if (type.Module == _member.Module)
+ return _module.GetOrCreateTypeSymbol(type);
+ else
+ return base.ResolveTypeSymbol(type);
+ }
+
+ ///
+ /// Resolves the symbol for the specified constructor.
+ ///
+ ///
+ ///
+ protected internal override ReflectionConstructorSymbol 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);
+ else
+ return base.ResolveConstructorSymbol(ctor);
+ }
+
+ ///
+ /// Resolves the symbol for the specified method.
+ ///
+ ///
+ ///
+ protected internal override ReflectionMethodSymbol 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);
+ else
+ return base.ResolveMethodSymbol(method);
+ }
+
+ ///
+ /// Resolves the symbol for the specified field.
+ ///
+ ///
+ ///
+ protected internal override ReflectionFieldSymbol 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);
+ else
+ return base.ResolveFieldSymbol(field);
+ }
+
+
+ ///
+ /// Resolves the symbol for the specified field.
+ ///
+ ///
+ ///
+ protected internal override ReflectionPropertySymbol 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);
+ else
+ return base.ResolvePropertySymbol(property);
+ }
+
+ ///
+ /// Resolves the symbol for the specified event.
+ ///
+ ///
+ ///
+ protected internal override ReflectionEventSymbol 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);
+ 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 ReflectionModuleSymbol ContainingModule => _module;
+
+ ///
+ /// 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;
+
+ ///
+ public virtual IModuleSymbol Module => Context.GetOrCreateModuleSymbol(_member.Module);
+
+ ///
+ public virtual ITypeSymbol? DeclaringType => _member.DeclaringType is Type t ? Context.GetOrCreateTypeSymbol(t) : null;
+
+ ///
+ public virtual MemberTypes MemberType => _member.MemberType;
+
+ ///
+ public virtual int MetadataToken => _member.MetadataToken;
+
+ ///
+ public virtual string Name => _member.Name;
+
+ ///
+ public virtual CustomAttributeSymbol[] GetCustomAttributes()
+ {
+ return ResolveCustomAttributes(_member.GetCustomAttributesData());
+ }
+
+ ///
+ public virtual CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_member.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray();
+ }
+
+ ///
+ public virtual bool IsDefined(ITypeSymbol attributeType)
+ {
+ return _member.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs
new file mode 100644
index 0000000000..5f1aaa9aa4
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodBaseSymbol.cs
@@ -0,0 +1,154 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ abstract class ReflectionMethodBaseSymbol : ReflectionMemberSymbol, IMethodBaseSymbol
+ {
+
+ 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)
+ {
+ _method = method ?? throw new ArgumentNullException(nameof(method));
+ }
+
+ ///
+ /// 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 == _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;
+ }
+
+ ///
+ /// Gets the underlying wrapped by this symbol.
+ ///
+ internal new MethodBase ReflectionObject => _method;
+
+ ///
+ public MethodAttributes Attributes => _method.Attributes;
+
+ ///
+ public CallingConventions CallingConvention => _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 MethodImplAttributes MethodImplementationFlags => _method.MethodImplementationFlags;
+
+ ///
+ public ITypeSymbol[] GetGenericArguments()
+ {
+ return ResolveTypeSymbols(_method.GetGenericArguments());
+ }
+
+ ///
+ public MethodImplAttributes GetMethodImplementationFlags()
+ {
+ return _method.GetMethodImplementationFlags();
+ }
+
+ ///
+ public IParameterSymbol[] GetParameters()
+ {
+ return ResolveParameterSymbols(_method.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
new file mode 100644
index 0000000000..fdbb45b38b
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionMethodSymbol.cs
@@ -0,0 +1,141 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ class ReflectionMethodSymbol : ReflectionMethodBaseSymbol, IMethodSymbol
+ {
+
+ readonly MethodInfo _method;
+
+ Type[]? _genericParametersSource;
+ ReflectionTypeSymbol?[]? _genericParameters;
+ List<(Type[] Arguments, ReflectionMethodSymbol Symbol)>? _genericTypes;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public ReflectionMethodSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, ReflectionTypeSymbol? type, MethodInfo method) :
+ base(context, module, type, method)
+ {
+ _method = method ?? throw new ArgumentNullException(nameof(method));
+ }
+
+ ///
+ /// 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
+ var sym = new ReflectionMethodSymbol(Context, ContainingModule, ContainingType, _method.MakeGenericMethod(genericMethodArguments));
+ _genericTypes.Add((genericMethodArguments, sym));
+ return sym;
+ }
+ }
+
+ ///
+ /// 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 ICustomAttributeSymbolProvider 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)));
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs
new file mode 100644
index 0000000000..3b96124816
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionModuleSymbol.cs
@@ -0,0 +1,352 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Metadata.Ecma335;
+using System.Threading;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ ///
+ /// Implementation of derived from System.Reflection.
+ ///
+ class ReflectionModuleSymbol : ReflectionSymbol, 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)
+ {
+#if NET
+ return type.IsTypeDefinition;
+#else
+ return type.HasElementType == false && type.IsConstructedGenericType == false && type.IsGenericParameter == false;
+#endif
+ }
+
+ readonly Module _module;
+
+ Type[]? _typesSource;
+ int _typesBaseRow;
+ ReflectionTypeSymbol?[]? _types;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public ReflectionModuleSymbol(ReflectionSymbolContext context, Module module) :
+ base(context)
+ {
+ _module = module ?? throw new ArgumentNullException(nameof(module));
+ }
+
+ ///
+ /// Gets the wrapped .
+ ///
+ internal Module ReflectionModule => _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 not a definition, but is substituted
+ if (IsTypeDefinition(type) == false)
+ return GetOrCreateTypeSymbolForSpecification(type);
+
+ // look up handle and row
+ var hnd = MetadataTokens.TypeDefinitionHandle(type.MetadataToken);
+ var row = MetadataTokens.GetRowNumber(hnd);
+
+ // initialize source table
+ if (_typesSource == null)
+ {
+ Interlocked.CompareExchange(ref _typesSource, _module.GetTypes().OrderBy(i => i.MetadataToken).ToArray(), null);
+ _typesBaseRow = _typesSource.Length != 0 ? MetadataTokens.GetRowNumber(MetadataTokens.MethodDefinitionHandle(_typesSource[0].MetadataToken)) : 0;
+ }
+
+ // 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;
+ if (idx < 0)
+ throw new Exception();
+
+ 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
+ ///
+ ///
+ ///
+ 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 = GetOrCreateTypeSymbol(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 definitionType = type.GetGenericTypeDefinition();
+ var definitionTypeSymbol = GetOrCreateTypeSymbol(definitionType);
+ 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);
+ 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);
+ return declaringMethod.GetOrCreateGenericParameterSymbol(type);
+ }
+
+ 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, BindingFlags bindingAttr)
+ {
+ return _module.GetField(name, bindingAttr) is { } f ? ResolveFieldSymbol(f) : null;
+ }
+
+ ///
+ public IFieldSymbol[] GetFields(BindingFlags bindingFlags)
+ {
+ return ResolveFieldSymbols(_module.GetFields(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, UnpackTypeSymbols(types)) 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;
+ }
+
+ ///
+ public IMethodSymbol[] GetMethods()
+ {
+ return ResolveMethodSymbols(_module.GetMethods());
+ }
+
+ ///
+ public IMethodSymbol[] GetMethods(BindingFlags bindingFlags)
+ {
+ return ResolveMethodSymbols(_module.GetMethods(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)
+ {
+ 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;
+ }
+
+ ///
+ public IMemberSymbol? ResolveMember(int metadataToken)
+ {
+ return _module.ResolveMember(metadataToken) is { } m ? ResolveMemberSymbol(m) : null;
+ }
+
+ ///
+ 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;
+ }
+
+ ///
+ 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;
+ }
+
+ ///
+ 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)
+ {
+ var _genericTypeArguments = genericTypeArguments != null ? UnpackTypeSymbols(genericTypeArguments) : null;
+ var _genericMethodArguments = genericMethodArguments != null ? UnpackTypeSymbols(genericMethodArguments) : null;
+ return ResolveTypeSymbol(_module.ResolveType(metadataToken, _genericTypeArguments, _genericMethodArguments));
+ }
+
+ ///
+ public CustomAttributeSymbol[] GetCustomAttributes()
+ {
+ return ResolveCustomAttributes(_module.GetCustomAttributesData());
+ }
+
+ ///
+ public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_module.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray();
+ }
+
+ ///
+ public bool IsDefined(ITypeSymbol attributeType)
+ {
+ return _module.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject);
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs
new file mode 100644
index 0000000000..1bf805672e
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionParameterSymbol.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ class ReflectionParameterSymbol : ReflectionSymbol, IParameterSymbol
+ {
+
+ readonly ParameterInfo _parameter;
+ readonly ReflectionMethodBaseSymbol _method;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public ReflectionParameterSymbol(ReflectionSymbolContext context, ReflectionMethodBaseSymbol method, ParameterInfo parameter) :
+ base(context)
+ {
+ _method = method ?? throw new ArgumentNullException(nameof(method));
+ _parameter = parameter ?? throw new ArgumentNullException(nameof(parameter));
+ }
+
+ internal ReflectionMethodBaseSymbol ContainingMethod => _method;
+
+ public ParameterAttributes Attributes => _parameter.Attributes;
+
+ public object? DefaultValue => _parameter.DefaultValue;
+
+ 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()
+ {
+ return ResolveCustomAttributes(_parameter.GetCustomAttributesData());
+ }
+
+ public CustomAttributeSymbol[] GetCustomAttributes(ITypeSymbol attributeType)
+ {
+ return ResolveCustomAttributes(_parameter.GetCustomAttributesData()).Where(i => i.AttributeType == attributeType).ToArray();
+ }
+
+ public bool IsDefined(ITypeSymbol attributeType)
+ {
+ return _parameter.IsDefined(((ReflectionTypeSymbol)attributeType).ReflectionObject);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs
new file mode 100644
index 0000000000..8e82493beb
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionPropertySymbol.cs
@@ -0,0 +1,117 @@
+using System;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ class ReflectionPropertySymbol : ReflectionMemberSymbol, IPropertySymbol
+ {
+
+ readonly PropertyInfo _property;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public ReflectionPropertySymbol(ReflectionSymbolContext context, ReflectionTypeSymbol type, PropertyInfo property) :
+ base(context, type.ContainingModule, type, property)
+ {
+ _property = property ?? throw new ArgumentNullException(nameof(property));
+ }
+
+ ///
+ /// Gets the underlying wrapped by this symbol.
+ ///
+ internal new PropertyInfo ReflectionObject => _property;
+
+ ///
+ public PropertyAttributes Attributes => _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());
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs
new file mode 100644
index 0000000000..03ad96cf32
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbol.cs
@@ -0,0 +1,418 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Reflection;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ ///
+ /// Base class for managed symbols.
+ ///
+ abstract class ReflectionSymbol : ISymbol
+ {
+
+ readonly ReflectionSymbolContext _context;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ public ReflectionSymbol(ReflectionSymbolContext context)
+ {
+ _context = context ?? throw new ArgumentNullException(nameof(context));
+ }
+
+ ///
+ /// Gets the associated .
+ ///
+ protected ReflectionSymbolContext Context => _context;
+
+ ///
+ public virtual bool IsMissing => false;
+
+ ///
+ /// Resolves the symbol for the specified type.
+ ///
+ ///
+ ///
+ protected virtual internal ReflectionModuleSymbol ResolveModuleSymbol(Module module)
+ {
+ return _context.GetOrCreateModuleSymbol(module);
+ }
+
+ ///
+ /// Resolves the symbols for the specified modules.
+ ///
+ ///
+ ///
+ protected internal ReflectionModuleSymbol[] ResolveModuleSymbols(Module[] modules)
+ {
+ var a = new ReflectionModuleSymbol[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);
+ }
+
+ ///
+ /// 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.
+ ///
+ ///
+ ///
+ protected virtual ReflectionMemberSymbol 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 ReflectionMemberSymbol[] ResolveMemberSymbols(MemberInfo[] types)
+ {
+ var a = new ReflectionMemberSymbol[types.Length];
+ for (int i = 0; i < types.Length; i++)
+ a[i] = ResolveMemberSymbol(types[i]);
+
+ 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.
+ ///
+ ///
+ ///
+ protected virtual internal ReflectionTypeSymbol ResolveTypeSymbol(Type type)
+ {
+ return _context.GetOrCreateTypeSymbol(type);
+ }
+
+ ///
+ /// Resolves the symbols for the specified types.
+ ///
+ ///
+ ///
+ protected internal ReflectionTypeSymbol[] ResolveTypeSymbols(Type[] types)
+ {
+ var a = new ReflectionTypeSymbol[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);
+ }
+
+ ///
+ /// 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.
+ ///
+ ///
+ ///
+ protected virtual internal ReflectionMethodBaseSymbol 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 ReflectionConstructorSymbol ResolveConstructorSymbol(ConstructorInfo ctor)
+ {
+ return _context.GetOrCreateConstructorSymbol(ctor);
+ }
+
+ ///
+ /// Resolves the symbols for the specified constructors.
+ ///
+ ///
+ ///
+ protected internal ReflectionConstructorSymbol[] ResolveConstructorSymbols(ConstructorInfo[] ctors)
+ {
+ var a = new ReflectionConstructorSymbol[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 ReflectionMethodSymbol ResolveMethodSymbol(MethodInfo method)
+ {
+ return _context.GetOrCreateMethodSymbol(method);
+ }
+
+ ///
+ /// Resolves the symbols for the specified methods.
+ ///
+ ///
+ ///
+ protected internal ReflectionMethodSymbol[] ResolveMethodSymbols(MethodInfo[] methods)
+ {
+ var a = new ReflectionMethodSymbol[methods.Length];
+ for (int i = 0; i < methods.Length; i++)
+ a[i] = ResolveMethodSymbol(methods[i]);
+
+ 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.
+ ///
+ ///
+ ///
+ protected virtual internal ReflectionFieldSymbol ResolveFieldSymbol(FieldInfo field)
+ {
+ return _context.GetOrCreateFieldSymbol(field);
+ }
+
+ ///
+ /// Resolves the symbols for the specified fields.
+ ///
+ ///
+ ///
+ protected internal ReflectionFieldSymbol[] ResolveFieldSymbols(FieldInfo[] fields)
+ {
+ var a = new ReflectionFieldSymbol[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 ReflectionPropertySymbol ResolvePropertySymbol(PropertyInfo property)
+ {
+ return _context.GetOrCreatePropertySymbol(property);
+ }
+
+ ///
+ /// Resolves the symbols for the specified properties.
+ ///
+ ///
+ ///
+ protected internal ReflectionPropertySymbol[] ResolvePropertySymbols(PropertyInfo[] properties)
+ {
+ var a = new ReflectionPropertySymbol[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 ReflectionEventSymbol ResolveEventSymbol(EventInfo @event)
+ {
+ return _context.GetOrCreateEventSymbol(@event);
+ }
+
+ ///
+ /// Resolves the symbols for the specified events.
+ ///
+ ///
+ ///
+ protected internal ReflectionEventSymbol[] ResolveEventSymbols(EventInfo[] events)
+ {
+ var a = new ReflectionEventSymbol[events.Length];
+ for (int i = 0; i < events.Length; i++)
+ a[i] = ResolveEventSymbol(events[i]);
+
+ return a;
+ }
+
+ ///
+ /// Transforms a custom set of custom attribute data records to a symbol record.
+ ///
+ ///
+ ///
+ protected internal CustomAttributeSymbol[] ResolveCustomAttributes(IList attributes)
+ {
+ var a = new CustomAttributeSymbol[attributes.Count];
+ for (int i = 0; i < attributes.Count; i++)
+ a[i] = ResolveCustomAttribute(attributes[i]);
+
+ return a;
+ }
+
+ ///
+ /// Transforms a custom attribute data record to a symbol record.
+ ///
+ ///
+ ///
+ ///
+ protected internal CustomAttributeSymbol ResolveCustomAttribute(CustomAttributeData customAttributeData)
+ {
+ return new CustomAttributeSymbol(
+ 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 CustomAttributeSymbolTypedArgument[args.Count];
+ for (int i = 0; i < args.Count; i++)
+ a[i] = ResolveCustomAttributeTypedArgument(args[i]);
+
+ return a.ToImmutableArray();
+ }
+
+ ///
+ /// Transforms a values into a symbol.
+ ///
+ ///
+ ///
+ CustomAttributeSymbolTypedArgument ResolveCustomAttributeTypedArgument(CustomAttributeTypedArgument arg)
+ {
+ return new CustomAttributeSymbolTypedArgument(ResolveTypeSymbol(arg.ArgumentType), arg.Value);
+ }
+
+ ///
+ /// Transforms a list of values into symbols.
+ ///
+ ///
+ ///
+ ImmutableArray ResolveCustomAttributeNamedArguments(IList args)
+ {
+ var a = new CustomAttributeSymbolNamedArgument[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.
+ ///
+ ///
+ ///
+ CustomAttributeSymbolNamedArgument ResolveCustomAttributeNamedArgument(CustomAttributeNamedArgument arg)
+ {
+ return new CustomAttributeSymbolNamedArgument(arg.IsField, ResolveMemberSymbol(arg.MemberInfo), arg.MemberName, ResolveCustomAttributeTypedArgument(arg.TypedValue));
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs
new file mode 100644
index 0000000000..b88ecdf06a
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionSymbolContext.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+namespace IKVM.CoreLib.Symbols.Reflection
+{
+
+ ///
+ /// Holds references to symbols derived from System.Reflection.
+ ///
+ class ReflectionSymbolContext
+ {
+
+ readonly ConditionalWeakTable _assemblies = new();
+
+ ///
+ /// Initializes a new instance.
+ ///
+ public ReflectionSymbolContext()
+ {
+
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public ReflectionAssemblySymbol GetOrCreateAssemblySymbol(Assembly assembly)
+ {
+ return _assemblies.GetValue(assembly, _ => new ReflectionAssemblySymbol(this, _));
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public ReflectionModuleSymbol GetOrCreateModuleSymbol(Module module)
+ {
+ return GetOrCreateAssemblySymbol(module.Assembly).GetOrCreateModuleSymbol(module);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public ReflectionTypeSymbol GetOrCreateTypeSymbol(Type type)
+ {
+ return GetOrCreateModuleSymbol(type.Module).GetOrCreateTypeSymbol(type);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public ReflectionConstructorSymbol GetOrCreateConstructorSymbol(ConstructorInfo ctor)
+ {
+ return GetOrCreateAssemblySymbol(ctor.Module.Assembly).GetOrCreateModuleSymbol(ctor.Module).GetOrCreateTypeSymbol(ctor.DeclaringType!).GetOrCreateConstructorSymbol(ctor);
+ }
+
+ ///
+ /// 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);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ 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);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public ReflectionFieldSymbol GetOrCreateFieldSymbol(FieldInfo field)
+ {
+ return GetOrCreateAssemblySymbol(field.Module.Assembly).GetOrCreateModuleSymbol(field.Module).GetOrCreateTypeSymbol(field.DeclaringType!).GetOrCreateFieldSymbol(field);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public ReflectionPropertySymbol GetOrCreatePropertySymbol(PropertyInfo property)
+ {
+ return GetOrCreateAssemblySymbol(property.Module.Assembly).GetOrCreateModuleSymbol(property.Module).GetOrCreateTypeSymbol(property.DeclaringType!).GetOrCreatePropertySymbol(property);
+ }
+
+ ///
+ /// Gets or creates a for the specified .
+ ///
+ ///
+ ///
+ public ReflectionEventSymbol GetOrCreateEventSymbol(EventInfo @event)
+ {
+ return GetOrCreateAssemblySymbol(@event.Module.Assembly).GetOrCreateModuleSymbol(@event.Module).GetOrCreateTypeSymbol(@event.DeclaringType!).GetOrCreateEventSymbol(@event);
+ }
+
+ }
+
+}
diff --git a/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs
new file mode 100644
index 0000000000..df9b1ffe70
--- /dev/null
+++ b/src/IKVM.CoreLib/Symbols/Reflection/ReflectionTypeSymbol.cs
@@ -0,0 +1,845 @@
+using System;
+using System.Collections.Generic;
+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;
+
+ FieldInfo[]? _fieldsSource;
+ int _fieldsBaseRow;
+ ReflectionFieldSymbol?[]? _fields;
+
+ PropertyInfo[]? _propertiesSource;
+ int _propertiesBaseRow;
+ ReflectionPropertySymbol?[]? _properties;
+
+ EventInfo[]? _eventsSource;
+ int _eventsBaseRow;
+ ReflectionEventSymbol?[]? _events;
+
+ ReflectionTypeSymbol?[]? _asArray;
+ ReflectionTypeSymbol? _asSZArray;
+ ReflectionTypeSymbol? _asPointer;
+ ReflectionTypeSymbol? _asByRef;
+
+ Type[]? _genericParametersSource;
+ ReflectionTypeSymbol?[]? _genericParameters;
+ List<(Type[] Arguments, ReflectionTypeSymbol Symbol)>? _genericTypes;
+ ReaderWriterLockSlim? _genericTypesLock;
+
+ ///
+ /// Initializes a new instance.
+ ///
+ ///
+ ///
+ ///
+ public ReflectionTypeSymbol(ReflectionSymbolContext context, ReflectionModuleSymbol module, Type type) :
+ base(context, module, null, type)
+ {
+ Debug.Assert(module.ReflectionModule == 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.
+ ///
+ ///
+ ///
+ ///
+ internal ReflectionTypeSymbol 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 ReflectionTypeSymbol?[_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 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)
+ {
+ if (genericTypeArguments is null)
+ throw new ArgumentNullException(nameof(genericTypeArguments));
+
+ 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();
+
+ // 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 ReflectionTypeSymbol(Context, ContainingModule, _type.MakeGenericType(genericTypeArguments));
+ _genericTypes.Add((genericTypeArguments, sym));
+ return sym;
+ }
+ finally
+ {
+ _genericTypesLock.ExitWriteLock();
+ }
+ }
+ finally
+ {
+ _genericTypesLock.ExitUpgradeableReadLock();
+ }
+ }
+
+ ///
+ /// Resolves the symbol for the specified type.
+ ///
+ ///
+ ///
+ protected internal override ReflectionTypeSymbol ResolveTypeSymbol(Type type)
+ {
+ if (type == _type)
+ return this;
+ else
+ 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 GenericParameterAttributes GenericParameterAttributes => _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 IsArray => _type.IsArray;
+
+ public bool IsAutoLayout => _type.IsAutoLayout;
+
+ 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 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 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;
+ }
+
+ 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(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()
+ {
+ return ResolveTypeSymbols(_type.GetInterfaces());
+ }
+
+ 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;
+ }
+
+ public IMethodSymbol? GetMethod(string name, BindingFlags bindingAttr, ITypeSymbol[] types)
+ {
+ return _type.GetMethod(name, bindingAttr, null, UnpackTypeSymbols(types), 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public bool IsAssignableFrom(ITypeSymbol? c)
+ {
+ return _type.IsAssignableFrom(c != null ? ((ReflectionTypeSymbol)c).ReflectionObject : null);
+ }
+
+ public bool IsEnumDefined(object value)
+ {
+ return _type.IsEnumDefined(value);
+ }
+
+ public bool IsSubclassOf(ITypeSymbol c)
+ {
+ return _type.IsSubclassOf(((ReflectionTypeSymbol)c).ReflectionObject);
+ }
+
+ public ITypeSymbol MakeArrayType()
+ {
+ if (_asSZArray == null)
+ Interlocked.CompareExchange(ref _asSZArray, new ReflectionTypeSymbol(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 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 asArray;
+ }
+
+ public ITypeSymbol MakeByRefType()
+ {
+ if (_asByRef == null)
+ Interlocked.CompareExchange(ref _asByRef, new ReflectionTypeSymbol(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 ReflectionTypeSymbol(Context, ContainingModule, _type.MakePointerType()), null);
+
+ return _asPointer;
+ }
+
+ }
+
+}
diff --git a/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj b/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj
index 1d174e816f..230f64d71c 100644
--- a/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj
+++ b/src/IKVM.Reflection.Tests/IKVM.Reflection.Tests.csproj
@@ -1,6 +1,6 @@
- net472;net6.0;net7.0;net8.0
+ net472;net6.0;net8.0
diff --git a/src/IKVM.Reflection/IKVM.Reflection.csproj b/src/IKVM.Reflection/IKVM.Reflection.csproj
index 89c0e0f0dd..ce87f7cbca 100644
--- a/src/IKVM.Reflection/IKVM.Reflection.csproj
+++ b/src/IKVM.Reflection/IKVM.Reflection.csproj
@@ -1,7 +1,7 @@
- net472;net6.0;net7.0;net8.0
+ net472;net6.0;net8.0
IKVM implementation of System.Reflection[.Emit]
true
11
diff --git a/src/IKVM.Reflection/Universe.cs b/src/IKVM.Reflection/Universe.cs
index 37b45b982d..e933bc87af 100644
--- a/src/IKVM.Reflection/Universe.cs
+++ b/src/IKVM.Reflection/Universe.cs
@@ -603,42 +603,7 @@ Assembly DefaultResolver(string refname, bool throwOnError)
if (asm != null)
return asm;
-#if NETFRAMEWORK
-
- string fileName;
- if (throwOnError)
- {
- try
- {
- fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
- }
- catch (System.BadImageFormatException x)
- {
- throw new BadImageFormatException(x.Message, x);
- }
- }
- else
- {
- try
- {
- fileName = System.Reflection.Assembly.ReflectionOnlyLoad(refname).Location;
- }
- catch (System.BadImageFormatException x)
- {
- throw new BadImageFormatException(x.Message, x);
- }
- catch (FileNotFoundException)
- {
- // we intentionally only swallow the FileNotFoundException, if the file exists but isn't a valid assembly,
- // we should throw an exception
- return null;
- }
- }
-
- return LoadFile(fileName);
-#else
return null;
-#endif
}
public Type GetType(string assemblyQualifiedTypeName)
diff --git a/src/IKVM.Runtime/Annotation.cs b/src/IKVM.Runtime/Annotation.cs
index dec264adf4..5ceea4735a 100644
--- a/src/IKVM.Runtime/Annotation.cs
+++ b/src/IKVM.Runtime/Annotation.cs
@@ -111,7 +111,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"));
+ return new RuntimeManagedByteCodeJavaType.CompiledAnnotation(owner.Context, owner.Context.Resolver.ResolveRuntimeType("IKVM.Attributes.DynamicAnnotationAttribute").AsReflection());
#else
return null;
#endif
diff --git a/src/IKVM.Runtime/AttributeHelper.cs b/src/IKVM.Runtime/AttributeHelper.cs
index cbd477d1c5..ea8b43babf 100644
--- a/src/IKVM.Runtime/AttributeHelper.cs
+++ b/src/IKVM.Runtime/AttributeHelper.cs
@@ -60,27 +60,27 @@ 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;
+ 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;
#endif
@@ -113,11 +113,11 @@ class AttributeHelper
#if IMPORTER
- Type TypeOfModifiers => typeofModifiers ??= LoadType(typeof(Modifiers));
+ Type TypeOfModifiers => typeofModifiers ??= LoadType(typeof(Modifiers));
- Type TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= LoadType(typeof(IKVM.Attributes.SourceFileAttribute));
+ Type TypeOfSourceFileAttribute => typeofSourceFileAttribute ??= LoadType(typeof(IKVM.Attributes.SourceFileAttribute));
- Type TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= LoadType(typeof(IKVM.Attributes.LineNumberTableAttribute));
+ Type TypeOfLineNumberTableAttribute => typeofLineNumberTableAttribute ??= LoadType(typeof(IKVM.Attributes.LineNumberTableAttribute));
#endif
@@ -165,7 +165,7 @@ class AttributeHelper
Type TypeOfConstantPoolAttribute => typeofConstantPoolAttribute ??= LoadType(typeof(ConstantPoolAttribute));
- Type TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveCoreType(typeof(DebuggableAttribute).FullName);
+ Type TypeOfDebuggableAttribute => typeofDebuggableAttribute ??= context.Resolver.ResolveCoreType(typeof(DebuggableAttribute).FullName).AsReflection();
CustomAttributeBuilder HideFromJavaAttributeBuilder => hideFromJavaAttribute ??= new CustomAttributeBuilder(TypeOfHideFromJavaAttribute.GetConstructor(Type.EmptyTypes), Array.Empty
diff --git a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs
index 054e1d80b4..d1f2ac4699 100644
--- a/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs
+++ b/src/IKVM.Tools.Exporter/ManagedTypeResolver.cs
@@ -1,73 +1,75 @@
using System;
+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 : IManagedTypeResolver
- {
+ class ManagedTypeResolver : ISymbolResolver
+ {
- readonly StaticCompiler compiler;
- readonly Assembly baseAssembly;
+ readonly StaticCompiler compiler;
+ readonly Assembly baseAssembly;
+ readonly IkvmReflectionSymbolContext context = new();
- ///
- /// Initializes a new instance.
- ///
- ///
- ///
- public ManagedTypeResolver(StaticCompiler compiler, Assembly baseAssembly)
- {
- this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler));
- this.baseAssembly = 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 Assembly ResolveBaseAssembly()
- {
- return baseAssembly;
- }
+ ///
+ /// Attempts to resolve the base Java assembly.
+ ///
+ ///
+ public IAssemblySymbol ResolveBaseAssembly()
+ {
+ return baseAssembly != null ? context.GetOrCreateAssemblySymbol(baseAssembly) : null;
+ }
- ///
- /// Attempts to resolve an assembly from one of the assembly sources.
- ///
- ///
- ///
- public Assembly ResolveAssembly(string assemblyName)
- {
- return compiler.Load(assemblyName);
- }
+ ///
+ /// Attempts to resolve an assembly from one of the assembly sources.
+ ///
+ ///
+ ///
+ public IAssemblySymbol ResolveAssembly(string assemblyName)
+ {
+ return compiler.Load(assemblyName) is { } a ? context.GetOrCreateAssemblySymbol(a) : null;
+ }
- ///
- /// Attempts to resolve a type from one of the assembly sources.
- ///
- ///
- ///
- public Type ResolveCoreType(string typeName)
- {
- foreach (var assembly in compiler.Universe.GetAssemblies())
- if (assembly.GetType(typeName) is Type t)
- return t;
+ ///
+ /// 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 context.GetOrCreateTypeSymbol(t);
- return null;
- }
+ return null;
+ }
- ///
- /// Attempts to resolve a type from the IKVM runtime assembly.
- ///
- ///
- ///
- public Type ResolveRuntimeType(string typeName)
- {
- return compiler.GetRuntimeType(typeName);
- }
+ ///
+ /// Attempts to resolve a type from the IKVM runtime assembly.
+ ///
+ ///
+ ///
+ public ITypeSymbol ResolveRuntimeType(string typeName)
+ {
+ return compiler.GetRuntimeType(typeName) is { } t ? context.GetOrCreateTypeSymbol(t) : null;
+ }
- }
+ }
}
diff --git a/src/IKVM.Tools.Exporter/RuntimeBootstrapClassLoader.cs b/src/IKVM.Tools.Exporter/RuntimeBootstrapClassLoader.cs
index 21cf1d0d51..12948e0eea 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), 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));
-
+ 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));
+
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"), context.PrimitiveJavaTypeFactory.VOID, Array.Empty(), Modifiers.Public | Modifiers.Abstract, MemberFlags.None, SimpleOpCode.Callvirt, SimpleOpCode.Callvirt) });
- SetRemappedType(Context.Resolver.ResolveCoreType(typeof(IDisposable).FullName), autoCloseable);
+ 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);
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.Importer/ImportClassLoader.cs b/src/IKVM.Tools.Importer/ImportClassLoader.cs
index b1797c5cf4..d3251bd5fc 100644
--- a/src/IKVM.Tools.Importer/ImportClassLoader.cs
+++ b/src/IKVM.Tools.Importer/ImportClassLoader.cs
@@ -547,13 +547,13 @@ void SetMain(RuntimeJavaType type, PEFileKinds target, IDictionary 0)
{
- var environmentType = Context.Resolver.ResolveCoreType(typeof(Environment).FullName);
- var environmentExpandMethod = environmentType.GetMethod(nameof(Environment.ExpandEnvironmentVariables), new[] { Context.Types.String });
- var dictionaryType = Context.Resolver.ResolveCoreType(typeof(Dictionary<,>).FullName).MakeGenericType(Context.Types.String, Context.Types.String);
- var dictionaryAddMethod = dictionaryType.GetMethod("Add", new[] { Context.Types.String, Context.Types.String });
+ var environmentType = Context.Resolver.ResolveCoreType(typeof(Environment).FullName).AsReflection();
+ 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 dictionaryAddMethod = dictionaryType.GetMethod("Add", [Context.Types.String, Context.Types.String]);
ilgen.EmitLdc_I4(properties.Count);
- ilgen.Emit(OpCodes.Newobj, dictionaryType.GetConstructor(new[] { Context.Types.Int32 }));
+ ilgen.Emit(OpCodes.Newobj, dictionaryType.GetConstructor([Context.Types.Int32]));
foreach (var kvp in properties)
{
@@ -575,7 +575,7 @@ void SetMain(RuntimeJavaType type, PEFileKinds target, IDictionary remappedType
if (hasfail)
{
ilgen.MarkLabel(fail);
- ilgen.ThrowException(Context.Resolver.ResolveCoreType(typeof(InvalidCastException).FullName));
+ ilgen.ThrowException(Context.Resolver.ResolveCoreType(typeof(InvalidCastException).FullName).AsReflection());
}
ilgen.DoEmit();
@@ -2277,7 +2277,7 @@ internal void Emit(MapXml.CodeGenContext context, CodeEmitter ilgen)
for (int i = 0; i < map.Length; i++)
{
ilgen.Emit(OpCodes.Dup);
- ilgen.Emit(OpCodes.Ldtoken, rcontext.Resolver.ResolveCoreType(map[i].Source));
+ ilgen.Emit(OpCodes.Ldtoken, rcontext.Resolver.ResolveCoreType(map[i].Source).AsReflection());
ilgen.Emit(OpCodes.Call, rcontext.CompilerFactory.GetTypeFromHandleMethod);
ilgen.Emit(OpCodes.Ceq);
var label = ilgen.DefineLabel();
@@ -2858,8 +2858,8 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag
if (options.bootstrap == false)
{
- allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveBaseAssembly());
- loader.AddReference(context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveBaseAssembly()));
+ allReferencesAreStrongNamed &= IsSigned(context.Resolver.ResolveBaseAssembly().AsReflection());
+ loader.AddReference(context.AssemblyClassLoaderFactory.FromAssembly(context.Resolver.ResolveBaseAssembly().AsReflection()));
}
if ((options.keyPair != null || options.publicKey != null) && !allReferencesAreStrongNamed)
@@ -2875,7 +2875,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag
if (options.bootstrap == false)
{
loader.fakeTypes = context.FakeTypes;
- loader.fakeTypes.Load(context.Resolver.ResolveBaseAssembly());
+ loader.fakeTypes.Load(context.Resolver.ResolveBaseAssembly().AsReflection());
}
return 0;
@@ -2883,7 +2883,7 @@ static int CreateCompiler(RuntimeContext context, StaticCompiler compiler, IDiag
static bool IsBaseAssembly(RuntimeContext context, Assembly asm)
{
- return asm.IsDefined(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.RemappedClassAttribute).FullName), false);
+ return asm.IsDefined(context.Resolver.ResolveRuntimeType(typeof(IKVM.Attributes.RemappedClassAttribute).FullName).AsReflection(), false);
}
private static Assembly LoadReferencedAssembly(StaticCompiler compiler, string r)
@@ -3014,7 +3014,7 @@ int CompilePass3()
_ => throw new NotImplementedException(),
};
- SetMain(wrapper, state.target, state.props, state.noglobbing, apartmentAttributeType);
+ SetMain(wrapper, state.target, state.props, state.noglobbing, apartmentAttributeType.AsReflection());
}
// complete map
@@ -3045,7 +3045,7 @@ int CompilePass3()
// configure Win32 file version
if (state.fileversion != null)
{
- var filever = new CustomAttributeBuilder(Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFileVersionAttribute).FullName).GetConstructor(new Type[] { Context.Types.String }), new object[] { state.fileversion });
+ var filever = new CustomAttributeBuilder(Context.Resolver.ResolveCoreType(typeof(System.Reflection.AssemblyFileVersionAttribute).FullName).AsReflection().GetConstructor([Context.Types.String]), [state.fileversion]);
assemblyBuilder.SetCustomAttribute(filever);
}
@@ -3090,7 +3090,7 @@ int CompilePass3()
throw new FatalCompilerErrorException(DiagnosticEvent.ClassLoaderConstructorMissing());
// apply custom attribute specifying custom class loader
- var ci = Context.Resolver.ResolveRuntimeType(typeof(CustomAssemblyClassLoaderAttribute).FullName).GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { Context.Types.Type }, null);
+ 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 }));
// the class loader type defines a module initialize method, ensure we call it upon module load
@@ -3100,9 +3100,9 @@ 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) }));
- il.Emit(OpCodes.Callvirt, Context.Resolver.ResolveCoreType(typeof(System.Reflection.MemberInfo).FullName).GetProperty("Module").GetGetMethod());
- il.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType("IKVM.Runtime.ByteCodeHelper").GetMethod("InitializeModule"));
+ 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());
});
}
}
diff --git a/src/IKVM.Tools.Importer/ImportContext.cs b/src/IKVM.Tools.Importer/ImportContext.cs
index 0bb36283f2..1ef1ea8e7a 100644
--- a/src/IKVM.Tools.Importer/ImportContext.cs
+++ b/src/IKVM.Tools.Importer/ImportContext.cs
@@ -31,6 +31,7 @@ Jeroen Frijters
using IKVM.ByteCode;
using IKVM.CoreLib.Diagnostics;
+using IKVM.CoreLib.Symbols;
using IKVM.Reflection;
using IKVM.Reflection.Emit;
using IKVM.Runtime;
@@ -184,14 +185,14 @@ static int Compile(ImportOptions options)
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);
compiler.rootTarget = rootTarget;
var importer = new ImportContext();
diff --git a/src/IKVM.Tools.Importer/ManagedResolver.cs b/src/IKVM.Tools.Importer/ManagedResolver.cs
index 496205ff9e..2b6ec0e4e6 100644
--- a/src/IKVM.Tools.Importer/ManagedResolver.cs
+++ b/src/IKVM.Tools.Importer/ManagedResolver.cs
@@ -23,17 +23,19 @@ Jeroen Frijters
*/
using System;
-using IKVM.Reflection;
-using IKVM.Runtime;
+using IKVM.CoreLib.Symbols;
+using IKVM.CoreLib.Symbols.IkvmReflection;
using Type = IKVM.Reflection.Type;
namespace IKVM.Tools.Importer
{
- class ManagedResolver : IManagedTypeResolver
+
+ class ManagedResolver : ISymbolResolver
{
readonly StaticCompiler compiler;
+ readonly IkvmReflectionSymbolContext context = new();
///
/// Initializes a new instance.
@@ -44,28 +46,28 @@ public ManagedResolver(StaticCompiler compiler)
this.compiler = compiler ?? throw new ArgumentNullException(nameof(compiler));
}
- public Assembly ResolveBaseAssembly()
+ public IAssemblySymbol ResolveBaseAssembly()
{
- return compiler.baseAssembly;
+ return compiler.baseAssembly != null ? context.GetOrCreateAssemblySymbol(compiler.baseAssembly) : null;
}
- public Assembly ResolveAssembly(string assemblyName)
+ public IAssemblySymbol ResolveAssembly(string assemblyName)
{
- return compiler.Universe.Load(assemblyName);
+ return compiler.Universe.Load(assemblyName) is { } a ? context.GetOrCreateAssemblySymbol(a) : null;
}
- public Type ResolveCoreType(string typeName)
+ public ITypeSymbol ResolveCoreType(string typeName)
{
foreach (var assembly in compiler.Universe.GetAssemblies())
if (assembly.GetType(typeName) is Type t)
- return t;
+ return context.GetOrCreateTypeSymbol(t);
return null;
}
- public Type ResolveRuntimeType(string typeName)
+ public ITypeSymbol ResolveRuntimeType(string typeName)
{
- return compiler.GetRuntimeType(typeName);
+ return compiler.GetRuntimeType(typeName) is { } t ? context.GetOrCreateTypeSymbol(t) : null;
}
}
diff --git a/src/IKVM.Tools.Importer/MapXml/Call.cs b/src/IKVM.Tools.Importer/MapXml/Call.cs
index 6771ddd455..f0f135ef52 100644
--- a/src/IKVM.Tools.Importer/MapXml/Call.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Call.cs
@@ -100,8 +100,9 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen
if (Name == ".ctor")
{
Debug.Assert(Class == null && Type != null);
- Type[] argTypes = context.ClassLoader.ArgTypeListFromSig(Sig);
- ConstructorInfo ci = context.ClassLoader.Context.Resolver.ResolveCoreType(Type).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, CallingConventions.Standard, argTypes, 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);
if (ci == null)
{
throw new InvalidOperationException("Missing .ctor: " + Type + "..ctor" + Sig);
@@ -195,17 +196,17 @@ internal sealed override void Generate(CodeGenContext context, CodeEmitter ilgen
argTypes = new Type[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.ResolveCoreType(types[i]).AsReflection();
}
}
- Type ti = context.ClassLoader.Context.Resolver.ResolveCoreType(Type);
+ var ti = context.ClassLoader.Context.Resolver.ResolveCoreType(Type).AsReflection();
if (ti == null)
{
throw new InvalidOperationException("Missing type: " + Type);
}
- MethodInfo 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, null, argTypes, null);
if (mi == null)
{
var ta = argTypes.Select(i => i.AssemblyQualifiedName).ToArray();
diff --git a/src/IKVM.Tools.Importer/MapXml/Redirect.cs b/src/IKVM.Tools.Importer/MapXml/Redirect.cs
index cdfea759d3..57951eaef6 100644
--- a/src/IKVM.Tools.Importer/MapXml/Redirect.cs
+++ b/src/IKVM.Tools.Importer/MapXml/Redirect.cs
@@ -85,7 +85,7 @@ 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);
+ var type = loader.Context.Resolver.ResolveCoreType(Type).AsReflection();
var mi = type.GetMethod(Name, redirParamTypes);
if (mi == null)
{
diff --git a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs
index b30c549e16..37c22bb2a1 100644
--- a/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs
+++ b/src/IKVM.Tools.Importer/RuntimeImportByteCodeJavaType.cs
@@ -828,7 +828,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).GetMethod("IsGhostArrayInstance", BindingFlags.NonPublic | BindingFlags.Static));
+ ilgen.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.GhostTag).FullName).AsReflection().GetMethod("IsGhostArrayInstance", BindingFlags.NonPublic | BindingFlags.Static));
ilgen.Emit(OpCodes.Ret);
ilgen.DoEmit();
@@ -881,7 +881,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).GetMethod("ThrowClassCastException", BindingFlags.NonPublic | BindingFlags.Static));
+ ilgen.Emit(OpCodes.Call, Context.Resolver.ResolveRuntimeType(typeof(IKVM.Runtime.GhostTag).FullName).AsReflection().GetMethod("ThrowClassCastException", BindingFlags.NonPublic | BindingFlags.Static));
ilgen.MarkLabel(end);
ilgen.Emit(OpCodes.Ret);
ilgen.DoEmit();
diff --git a/src/dist-tests/dist-tests.csproj b/src/dist-tests/dist-tests.csproj
index 019371a15d..00db3fc0c7 100644
--- a/src/dist-tests/dist-tests.csproj
+++ b/src/dist-tests/dist-tests.csproj
@@ -9,8 +9,10 @@
-
+
+
+
diff --git a/src/ikvmc/Properties/launchSettings.json b/src/ikvmc/Properties/launchSettings.json
index b3249c1914..31d9cf8012 100644
--- a/src/ikvmc/Properties/launchSettings.json
+++ b/src/ikvmc/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"ikvmc": {
"commandName": "Project",
- "commandLineArgs": "@C:\\Users\\jhaltom\\AppData\\Local\\Temp\\31187b7c-3061-4bf2-96d0-c1cb9fa41ecb\\helloworld\\ikvmc.rsp"
+ "commandLineArgs": "@D:\\ikvm\\src\\IKVM.Java\\obj\\Debug\\net8.0\\IKVM.Java.ikvmc.rsp"
}
}
}