5 Commits
Author SHA1 Message Date
ds5678 7e3e7bfa8c Bump version 2025-01-11 01:07:46 -08:00
ds5678 777fb5ea1c Fix AddLoadIndirect and AddStoreIndirect
* Resolves #1
2025-01-11 01:07:24 -08:00
ds5678 be8f11f6b5 Fix incorrect field references for generic types 2025-01-10 23:47:59 -08:00
ds5678 1338ca2f95 Add method stubbing tool 2025-01-10 23:46:05 -08:00
ds5678 e95ff3bae6 Bump tools to .NET 9 2025-01-10 23:45:32 -08:00
11 changed files with 369 additions and 14 deletions

No files matched your search

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\AssetRipper.CIL\AssetRipper.CIL.csproj" />
</ItemGroup>
</Project>
+18
View File
@@ -0,0 +1,18 @@
using AsmResolver.DotNet;
namespace AssetRipper.CIL.Stubber
{
internal class Program
{
static void Main(string[] args)
{
ModuleDefinition module = ModuleDefinition.FromFile(args[0]);
foreach (MethodDefinition method in module.GetAllTypes().SelectMany(t => t.Methods))
{
method.ReplaceMethodBodyWithMinimalImplementation();
}
module.Write(args[1]);
Console.WriteLine("Done!");
}
}
}
@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit.Analyzers" Version="4.6.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AssetRipper.CIL\AssetRipper.CIL.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>
</Project>
+113
View File
@@ -0,0 +1,113 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
namespace AssetRipper.CIL.Tests;
public class LoadIndirectTests
{
[TestCase(ElementType.I1, CilCode.Ldind_I1)]
[TestCase(ElementType.I2, CilCode.Ldind_I2)]
[TestCase(ElementType.I4, CilCode.Ldind_I4)]
[TestCase(ElementType.I8, CilCode.Ldind_I8)]
[TestCase(ElementType.U1, CilCode.Ldind_U1)]
[TestCase(ElementType.U2, CilCode.Ldind_U2)]
[TestCase(ElementType.U4, CilCode.Ldind_U4)]
[TestCase(ElementType.U8, CilCode.Ldind_I8)]
[TestCase(ElementType.I, CilCode.Ldind_I)]
[TestCase(ElementType.U, CilCode.Ldind_I)]
[TestCase(ElementType.R4, CilCode.Ldind_R4)]
[TestCase(ElementType.R8, CilCode.Ldind_R8)]
[TestCase(ElementType.Boolean, CilCode.Ldind_U1)]
[TestCase(ElementType.Char, CilCode.Ldind_U2)]
[TestCase(ElementType.Object, CilCode.Ldind_Ref)]
[TestCase(ElementType.String, CilCode.Ldind_Ref)]
[TestCase(ElementType.TypedByRef, CilCode.Ldobj)]
public void CorlibLoadIndirect(ElementType type, CilCode code)
{
ModuleDefinition module = new ModuleDefinition("TestModule");
CorLibTypeSignature? typeToLoad = module.CorLibTypeFactory.FromElementType(type);
Assert.That(typeToLoad, Is.Not.Null);
AssertCorrectLoadIndirect(typeToLoad, code);
}
[TestCase(ElementType.I1, CilCode.Ldind_I1)]
[TestCase(ElementType.I2, CilCode.Ldind_I2)]
[TestCase(ElementType.I4, CilCode.Ldind_I4)]
[TestCase(ElementType.I8, CilCode.Ldind_I8)]
[TestCase(ElementType.U1, CilCode.Ldind_U1)]
[TestCase(ElementType.U2, CilCode.Ldind_U2)]
[TestCase(ElementType.U4, CilCode.Ldind_U4)]
[TestCase(ElementType.U8, CilCode.Ldind_I8)]
public void EnumLoadIndirect(ElementType type, CilCode code)
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeSignature? typeToLoad = CreateEnum(module, type).ToTypeSignature();
Assert.That(typeToLoad, Is.Not.Null);
AssertCorrectLoadIndirect(typeToLoad, code);
}
[Test]
public void PointerLoadIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
PointerTypeSignature typeToLoad = module.CorLibTypeFactory.Void.MakePointerType();
AssertCorrectLoadIndirect(typeToLoad, CilCode.Ldind_I);
}
[Test]
public void GenericParameterLoadIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
GenericParameterSignature typeToLoad = new GenericParameterSignature(module, GenericParameterType.Type, 0);
AssertCorrectLoadIndirect(typeToLoad, CilCode.Ldobj);
}
[Test]
public void SzArrayLoadIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeSignature typeToLoad = module.CorLibTypeFactory.Int32.MakeSzArrayType();
AssertCorrectLoadIndirect(typeToLoad, CilCode.Ldind_Ref);
}
[Test]
public void ClassLoadIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeDefinition type = new TypeDefinition("TestNamespace", "TestName", TypeAttributes.Public, module.CorLibTypeFactory.Object.ToTypeDefOrRef());
module.TopLevelTypes.Add(type);
AssertCorrectLoadIndirect(type.ToTypeSignature(), CilCode.Ldind_Ref);
}
[Test]
public void StructLoadIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeDefinition type = new TypeDefinition("TestNamespace", "TestName", TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed, module.DefaultImporter.ImportType(typeof(ValueType)));
module.TopLevelTypes.Add(type);
AssertCorrectLoadIndirect(type.ToTypeSignature(), CilCode.Ldobj);
}
private static void AssertCorrectLoadIndirect(TypeSignature typeToLoad, CilCode expectedOpCode)
{
MethodDefinition method = new MethodDefinition("Test", MethodAttributes.Public | MethodAttributes.Static, null);
method.CilMethodBody = new(method);
CilInstructionCollection instructions = method.CilMethodBody.Instructions;
instructions.AddLoadIndirect(typeToLoad);
Assert.That(instructions, Has.Count.EqualTo(1));
Assert.That(instructions[0].OpCode.Code, Is.EqualTo(expectedOpCode));
}
private static TypeDefinition CreateEnum(ModuleDefinition module, ElementType underlyingType)
{
TypeDefinition enumType = new TypeDefinition("TestNamespace", "TestEnum", TypeAttributes.Public, module.DefaultImporter.ImportType(typeof(Enum)));
module.TopLevelTypes.Add(enumType);
CorLibTypeSignature underlyingTypeSignature = module.CorLibTypeFactory.FromElementType(underlyingType) ?? throw new NullReferenceException();
FieldDefinition valueField = new FieldDefinition("value__", FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RuntimeSpecialName, underlyingTypeSignature);
enumType.Fields.Add(valueField);
return enumType;
}
}
+113
View File
@@ -0,0 +1,113 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
namespace AssetRipper.CIL.Tests;
public class StoreIndirectTests
{
[TestCase(ElementType.I1, CilCode.Stind_I1)]
[TestCase(ElementType.I2, CilCode.Stind_I2)]
[TestCase(ElementType.I4, CilCode.Stind_I4)]
[TestCase(ElementType.I8, CilCode.Stind_I8)]
[TestCase(ElementType.U1, CilCode.Stind_I1)]
[TestCase(ElementType.U2, CilCode.Stind_I2)]
[TestCase(ElementType.U4, CilCode.Stind_I4)]
[TestCase(ElementType.U8, CilCode.Stind_I8)]
[TestCase(ElementType.I, CilCode.Stind_I)]
[TestCase(ElementType.U, CilCode.Stind_I)]
[TestCase(ElementType.R4, CilCode.Stind_R4)]
[TestCase(ElementType.R8, CilCode.Stind_R8)]
[TestCase(ElementType.Boolean, CilCode.Stind_I1)]
[TestCase(ElementType.Char, CilCode.Stind_I2)]
[TestCase(ElementType.Object, CilCode.Stind_Ref)]
[TestCase(ElementType.String, CilCode.Stind_Ref)]
[TestCase(ElementType.TypedByRef, CilCode.Stobj)]
public void CorlibStoreIndirect(ElementType type, CilCode code)
{
ModuleDefinition module = new ModuleDefinition("TestModule");
CorLibTypeSignature? typeToStore = module.CorLibTypeFactory.FromElementType(type);
Assert.That(typeToStore, Is.Not.Null);
AssertCorrectStoreIndirect(typeToStore, code);
}
[TestCase(ElementType.I1, CilCode.Stind_I1)]
[TestCase(ElementType.I2, CilCode.Stind_I2)]
[TestCase(ElementType.I4, CilCode.Stind_I4)]
[TestCase(ElementType.I8, CilCode.Stind_I8)]
[TestCase(ElementType.U1, CilCode.Stind_I1)]
[TestCase(ElementType.U2, CilCode.Stind_I2)]
[TestCase(ElementType.U4, CilCode.Stind_I4)]
[TestCase(ElementType.U8, CilCode.Stind_I8)]
public void EnumStoreIndirect(ElementType type, CilCode code)
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeSignature? typeToStore = CreateEnum(module, type).ToTypeSignature();
Assert.That(typeToStore, Is.Not.Null);
AssertCorrectStoreIndirect(typeToStore, code);
}
[Test]
public void PointerStoreIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
PointerTypeSignature typeToStore = module.CorLibTypeFactory.Void.MakePointerType();
AssertCorrectStoreIndirect(typeToStore, CilCode.Stind_I);
}
[Test]
public void GenericParameterStoreIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
GenericParameterSignature typeToStore = new GenericParameterSignature(module, GenericParameterType.Type, 0);
AssertCorrectStoreIndirect(typeToStore, CilCode.Stobj);
}
[Test]
public void SzArrayStoreIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeSignature typeToStore = module.CorLibTypeFactory.Int32.MakeSzArrayType();
AssertCorrectStoreIndirect(typeToStore, CilCode.Stind_Ref);
}
[Test]
public void ClassStoreIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeDefinition type = new TypeDefinition("TestNamespace", "TestName", TypeAttributes.Public, module.CorLibTypeFactory.Object.ToTypeDefOrRef());
module.TopLevelTypes.Add(type);
AssertCorrectStoreIndirect(type.ToTypeSignature(), CilCode.Stind_Ref);
}
[Test]
public void StructStoreIndirect()
{
ModuleDefinition module = new ModuleDefinition("TestModule");
TypeDefinition type = new TypeDefinition("TestNamespace", "TestName", TypeAttributes.Public | TypeAttributes.SequentialLayout | TypeAttributes.Sealed, module.DefaultImporter.ImportType(typeof(ValueType)));
module.TopLevelTypes.Add(type);
AssertCorrectStoreIndirect(type.ToTypeSignature(), CilCode.Stobj);
}
private static void AssertCorrectStoreIndirect(TypeSignature typeToStore, CilCode expectedOpCode)
{
MethodDefinition method = new MethodDefinition("Test", MethodAttributes.Public | MethodAttributes.Static, null);
method.CilMethodBody = new(method);
CilInstructionCollection instructions = method.CilMethodBody.Instructions;
instructions.AddStoreIndirect(typeToStore);
Assert.That(instructions, Has.Count.EqualTo(1));
Assert.That(instructions[0].OpCode.Code, Is.EqualTo(expectedOpCode));
}
private static TypeDefinition CreateEnum(ModuleDefinition module, ElementType underlyingType)
{
TypeDefinition enumType = new TypeDefinition("TestNamespace", "TestEnum", TypeAttributes.Public, module.DefaultImporter.ImportType(typeof(Enum)));
module.TopLevelTypes.Add(enumType);
CorLibTypeSignature underlyingTypeSignature = module.CorLibTypeFactory.FromElementType(underlyingType) ?? throw new NullReferenceException();
FieldDefinition valueField = new FieldDefinition("value__", FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RuntimeSpecialName, underlyingTypeSignature);
enumType.Fields.Add(valueField);
return enumType;
}
}
@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
+12
View File
@@ -18,6 +18,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AssetRipper.CIL.Validator",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.CIL.Standardizer", "AssetRipper.CIL.Standardizer\AssetRipper.CIL.Standardizer.csproj", "{9E6D8580-5C3C-4AA8-89C9-34F475B79B24}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.CIL.Stubber", "AssetRipper.CIL.Stubber\AssetRipper.CIL.Stubber.csproj", "{A35A3452-2211-4DF5-A5A5-406FDF1E1A76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AssetRipper.CIL.Tests", "AssetRipper.CIL.Tests\AssetRipper.CIL.Tests.csproj", "{FC03589F-7457-45E7-9628-F9E003F30BAB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -36,6 +40,14 @@ Global
{9E6D8580-5C3C-4AA8-89C9-34F475B79B24}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9E6D8580-5C3C-4AA8-89C9-34F475B79B24}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9E6D8580-5C3C-4AA8-89C9-34F475B79B24}.Release|Any CPU.Build.0 = Release|Any CPU
{A35A3452-2211-4DF5-A5A5-406FDF1E1A76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A35A3452-2211-4DF5-A5A5-406FDF1E1A76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A35A3452-2211-4DF5-A5A5-406FDF1E1A76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A35A3452-2211-4DF5-A5A5-406FDF1E1A76}.Release|Any CPU.Build.0 = Release|Any CPU
{FC03589F-7457-45E7-9628-F9E003F30BAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC03589F-7457-45E7-9628-F9E003F30BAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC03589F-7457-45E7-9628-F9E003F30BAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC03589F-7457-45E7-9628-F9E003F30BAB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -129,17 +129,36 @@ public static class CilInstructionCollectionExtensions
ElementType.I2 => instructions.Add(CilOpCodes.Ldind_I2),
ElementType.I4 => instructions.Add(CilOpCodes.Ldind_I4),
ElementType.I8 or ElementType.U8 => instructions.Add(CilOpCodes.Ldind_I8),
ElementType.U1 => instructions.Add(CilOpCodes.Ldind_U1),
ElementType.U2 => instructions.Add(CilOpCodes.Ldind_U2),
ElementType.U1 or ElementType.Boolean => instructions.Add(CilOpCodes.Ldind_U1),
ElementType.U2 or ElementType.Char => instructions.Add(CilOpCodes.Ldind_U2),
ElementType.U4 => instructions.Add(CilOpCodes.Ldind_U4),
ElementType.R4 => instructions.Add(CilOpCodes.Ldind_R4),
ElementType.R8 => instructions.Add(CilOpCodes.Ldind_R8),
ElementType.I or ElementType.U => instructions.Add(CilOpCodes.Ldind_I),
ElementType.Object or ElementType.String => instructions.Add(CilOpCodes.Ldind_Ref),
_ => instructions.Add(CilOpCodes.Ldobj, type.ToTypeDefOrRef()),
},
PointerTypeSignature => instructions.Add(CilOpCodes.Ldind_I),
_ => instructions.Add(CilOpCodes.Ldobj, type.ToTypeDefOrRef()),
GenericParameterSignature => instructions.Add(CilOpCodes.Ldobj, type.ToTypeDefOrRef()),
TypeDefOrRefSignature t => AddTypeDefOrRef(instructions, t),
_ => AddUnknown(instructions, type),
};
static CilInstruction AddUnknown(CilInstructionCollection instructions, TypeSignature type)
{
return type.IsValueType
? instructions.Add(CilOpCodes.Ldobj, type.ToTypeDefOrRef())
: instructions.Add(CilOpCodes.Ldind_Ref);
}
static CilInstruction AddTypeDefOrRef(CilInstructionCollection instructions, TypeDefOrRefSignature type)
{
// Check if the type is an enum
TypeSignature underlyingType = type.GetUnderlyingType();
return underlyingType is CorLibTypeSignature
? instructions.AddLoadIndirect(underlyingType)
: AddUnknown(instructions, underlyingType);
}
}
public static CilInstruction AddStoreIndirect(this CilInstructionCollection instructions, TypeSignature type)
@@ -152,17 +171,36 @@ public static class CilInstructionCollectionExtensions
ElementType.I2 => instructions.Add(CilOpCodes.Stind_I2),
ElementType.I4 => instructions.Add(CilOpCodes.Stind_I4),
ElementType.I8 or ElementType.U8 => instructions.Add(CilOpCodes.Stind_I8),
ElementType.U1 => instructions.Add(CilOpCodes.Stind_I1),
ElementType.U2 => instructions.Add(CilOpCodes.Stind_I2),
ElementType.U1 or ElementType.Boolean => instructions.Add(CilOpCodes.Stind_I1),
ElementType.U2 or ElementType.Char => instructions.Add(CilOpCodes.Stind_I2),
ElementType.U4 => instructions.Add(CilOpCodes.Stind_I4),
ElementType.R4 => instructions.Add(CilOpCodes.Stind_R4),
ElementType.R8 => instructions.Add(CilOpCodes.Stind_R8),
ElementType.I or ElementType.U => instructions.Add(CilOpCodes.Stind_I),
ElementType.Object or ElementType.String => instructions.Add(CilOpCodes.Stind_Ref),
_ => instructions.Add(CilOpCodes.Stobj, type.ToTypeDefOrRef()),
},
PointerTypeSignature => instructions.Add(CilOpCodes.Stind_I),
_ => instructions.Add(CilOpCodes.Stobj, type.ToTypeDefOrRef()),
GenericParameterSignature => instructions.Add(CilOpCodes.Stobj, type.ToTypeDefOrRef()),
TypeDefOrRefSignature t => AddTypeDefOrRef(instructions, t),
_ => AddUnknown(instructions, type),
};
static CilInstruction AddUnknown(CilInstructionCollection instructions, TypeSignature type)
{
return type.IsValueType
? instructions.Add(CilOpCodes.Stobj, type.ToTypeDefOrRef())
: instructions.Add(CilOpCodes.Stind_Ref);
}
static CilInstruction AddTypeDefOrRef(CilInstructionCollection instructions, TypeDefOrRefSignature type)
{
// Check if the type is an enum
TypeSignature underlyingType = type.GetUnderlyingType();
return underlyingType is CorLibTypeSignature
? instructions.AddStoreIndirect(underlyingType)
: AddUnknown(instructions, underlyingType);
}
}
/// <summary>
+19 -5
View File
@@ -23,12 +23,12 @@ internal static class MethodStubber
{
if (methodDefinition.IsStatic)
{
methodInstructions.Add(CilOpCodes.Ldsfld, backingField);
methodInstructions.Add(CilOpCodes.Ldsfld, backingField.MakeGenericIfNecessary());
}
else
{
methodInstructions.Add(CilOpCodes.Ldarg_0);
methodInstructions.Add(CilOpCodes.Ldfld, backingField);
methodInstructions.Add(CilOpCodes.Ldfld, backingField.MakeGenericIfNecessary());
}
methodInstructions.Add(CilOpCodes.Ret);
return;
@@ -38,13 +38,13 @@ internal static class MethodStubber
if (methodDefinition.IsStatic)
{
methodInstructions.Add(CilOpCodes.Ldarg_0);
methodInstructions.Add(CilOpCodes.Stsfld, backingField);
methodInstructions.Add(CilOpCodes.Stsfld, backingField.MakeGenericIfNecessary());
}
else
{
methodInstructions.Add(CilOpCodes.Ldarg_0);
methodInstructions.Add(CilOpCodes.Ldarg_1);
methodInstructions.Add(CilOpCodes.Stfld, backingField);
methodInstructions.Add(CilOpCodes.Stfld, backingField.MakeGenericIfNecessary());
}
methodInstructions.Add(CilOpCodes.Ret);
return;
@@ -62,7 +62,7 @@ internal static class MethodStubber
methodInstructions.Add(CilOpCodes.Ldarg_0);
methodInstructions.AddDefaultValue(field.Signature.FieldType);
methodInstructions.Add(CilOpCodes.Stfld, field);
methodInstructions.Add(CilOpCodes.Stfld, field.MakeGenericIfNecessary());
}
}
@@ -181,4 +181,18 @@ internal static class MethodStubber
baseConstructor = TryGetBaseConstructor(methodDefinition);
return baseConstructor is not null;
}
private static IFieldDescriptor MakeGenericIfNecessary(this FieldDefinition field)
{
if (field.DeclaringType is null or { GenericParameters.Count: 0 })
{
return field;
}
TypeSignature[] typeArguments = Enumerable.Range(0, field.DeclaringType.GenericParameters.Count)
.Select(i => new GenericParameterSignature(field.Module, GenericParameterType.Type, i))
.ToArray();
return new MemberReference(field.DeclaringType.MakeGenericInstanceType(typeArguments).ToTypeDefOrRef(), field.Name, field.Signature);
}
}
+1 -1
View File
@@ -6,7 +6,7 @@
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<PolySharpIncludeRuntimeSupportedAttributes>true</PolySharpIncludeRuntimeSupportedAttributes>
<Version>1.1.3</Version>
<Version>1.1.4</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<Copyright>Copyright (c) 2024 ds5678</Copyright>
<Authors>ds5678</Authors>