Skip to content

Commit

Permalink
Bugfix/could not resolve type system.runtime method handle (#6)
Browse files Browse the repository at this point in the history
* fix typos

* fix code

* add test cases

* remove code

* bump version

* remove some code
  • Loading branch information
huoshan12345 authored Oct 2, 2024
1 parent 21da4f0 commit 5c47006
Show file tree
Hide file tree
Showing 40 changed files with 319 additions and 279 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
dotnet-version: |
6.0.x
7.0.x
8.0.x
- name: Restore
run: dotnet restore ${{ env.SOLUTION }} -v q
Expand Down
3 changes: 3 additions & 0 deletions InterfaceBaseInvoke.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IL/@EntryIndexedValue">IL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateConstants/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PrivateStaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8783c43e_002De3b4_002D4c1d_002Dba9c_002D634febd1b3b7/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Protected" Description="Protected field"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CustomTools/CustomToolsData/@EntryValue"></s:String>
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=InlineIL_002EExamples_003B_002A_003B_002A_003B_002A/@EntryIndexedValue">True</s:Boolean>
Expand All @@ -50,6 +52,7 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002EXml_002ECodeStyle_002EFormatSettingsUpgrade_002EXmlMoveToCommonFormatterSettingsUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue">&lt;data /&gt;</s:String>
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters&gt;&lt;Filter ModuleMask="InlineIL.Tests.*" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="InlineIL.Examples" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;Filter ModuleMask="InlineIL" ModuleVersionMask="*" ClassMask="*" FunctionMask="*" IsEnabled="True" /&gt;&lt;/ExcludeFilters&gt;&lt;/data&gt;</s:String>
Expand Down
2 changes: 1 addition & 1 deletion NuGet.Config
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
<!--<add key="local" value="D:\projects\MoreFodyHelpers\build" />-->
<!--<add key="local" value="D:\projects\Fody\MoreFodyHelpers\build" />-->
</packageSources>
</configuration>
2 changes: 1 addition & 1 deletion build/pkg.version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.3
0.1.4
2 changes: 1 addition & 1 deletion src/InterfaceBaseInvoke.Example/FodyWeavers.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<InterfaceBaseInvoke />
</Weavers>
</Weavers>
14 changes: 12 additions & 2 deletions src/InterfaceBaseInvoke.Example/InterfaceBaseInvoke.Example.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Fody" Version="6.8.0" PrivateAssets="all" />
<PackageReference Include="Fody" Version="6.8.2" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand All @@ -21,4 +21,14 @@
<WeaverFiles Include="..\$(_WeaverName)\bin\$(Configuration)\netstandard2.0\$(_WeaverName).dll" />
</ItemGroup>

<Target Name="CheckWeaverFiles" BeforeTargets="Build">
<Message Importance="High" Text="WeaverFiles: @(WeaverFiles)" />
<Error Text="No weaver found at @(WeaverFiles)." Condition="!Exists(@(WeaverFiles))" />
</Target>

<!--<Target Name="CheckExecutedWeavers" AfterTargets="AfterCompile" Condition="!Exists(@(FodyExecutedWeavers))">
<Delete Files="@(IntermediateAssembly)" /> --><!--force to rebuild this project next time when it is not weaved.--><!--
<Error Text="No executed weaver found." />
</Target>-->

</Project>
39 changes: 0 additions & 39 deletions src/InterfaceBaseInvoke.Fody/Extensions/CecilExtensions.cs

This file was deleted.

1 change: 1 addition & 0 deletions src/InterfaceBaseInvoke.Fody/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@
global using MoreFodyHelpers.Building;
global using MoreFodyHelpers.Extensions;
global using MoreFodyHelpers.Processing;
global using MoreFodyHelpers.Support;
5 changes: 1 addition & 4 deletions src/InterfaceBaseInvoke.Fody/InterfaceBaseInvoke.Fody.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MoreFodyHelpers" Version="0.0.5" GeneratePathProperty="true" />
<None Include="$(PkgMoreFodyHelpers)\lib\$(TargetFramework)\MoreFodyHelpers.dll" Visible="false">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<PackageReference Include="MoreFodyHelpers" Version="0.0.8" GeneratePathProperty="true" />
</ItemGroup>
</Project>
64 changes: 38 additions & 26 deletions src/InterfaceBaseInvoke.Fody/ModuleWeaver.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,52 @@
namespace InterfaceBaseInvoke.Fody
namespace InterfaceBaseInvoke.Fody;

public class ModuleWeaver : BaseModuleWeaver
{
public class ModuleWeaver : BaseModuleWeaver
private readonly IWeaverLogger _log;

public ModuleWeaver()
{
private readonly IWeaverLogger _log;
_log = new WeaverLogger(this);
}

public ModuleWeaver()
{
_log = new WeaverLogger(this);
}
public override void Execute()
{
using var context = new ModuleWeavingContext(ModuleDefinition, WeaverAnchors.AssemblyName, ProjectDirectoryPath);

public override void Execute()
var processed = false;
foreach (var type in ModuleDefinition.GetTypes())
{
foreach (var type in ModuleDefinition.GetTypes())
foreach (var method in type.Methods)
{
foreach (var method in type.Methods)
if (method.HasBody == false)
continue;

_log.Debug($"Processing: {method.FullName}");

try
{
if (ModuleDefinition.IsAssemblyReferenced(method, WeaverAnchors.AssemblyName) == false)
continue;

_log.Debug($"Processing: {method.FullName}");

try
{
new MethodWeaver(ModuleDefinition, method, _log).Process();
}
catch (WeavingException ex)
{
AddError(ex.Message, ex.SequencePoint);
}
processed = new MethodWeaver(context, method, _log).Process() || processed;
}
catch (WeavingException ex)
{
var terminate = AddError(ex.ToString(), ex.SequencePoint);
if (terminate)
return;
}
}
}

public override IEnumerable<string> GetAssembliesForScanning() => Enumerable.Empty<string>();
if (processed == false)
{
_log.Warning("No type is processed.", null);
}
}

public override IEnumerable<string> GetAssembliesForScanning() => [];

protected virtual void AddError(string message, SequencePoint? sequencePoint)
=> _log.Error(message, sequencePoint);
protected virtual bool AddError(string message, SequencePoint? sequencePoint)
{
_log.Error(message, sequencePoint);
return true;
}
}
20 changes: 12 additions & 8 deletions src/InterfaceBaseInvoke.Fody/Processing/MethodWeaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,36 @@ namespace InterfaceBaseInvoke.Fody.Processing;

internal sealed class MethodWeaver
{
private readonly ModuleDefinition _module;
private readonly MethodDefinition _method;
private readonly MethodWeaverLogger _log;
private readonly WeaverILProcessor _il;
private readonly References _references;
private readonly SequencePointMapper _sequencePoints;

private Collection<Instruction> Instructions => _method.Body.Instructions;
private TypeReferences Types => _references.Types;
private MethodReferences Methods => _references.Methods;

public MethodWeaver(ModuleDefinition module, MethodDefinition method, IWeaverLogger log)
public MethodWeaver(ModuleWeavingContext context, MethodDefinition method, IWeaverLogger log)
{
_module = module;
_method = method;
_il = new WeaverILProcessor(method);
_log = new MethodWeaverLogger(log, _method);
_references = new References(module);
_references = new References(context);
_sequencePoints = new SequencePointMapper(method, true);
}

public void Process()
public bool Process()
{
try
{
ProcessImpl();
return ProcessImpl();
}
catch (InstructionWeavingException ex)
{
throw new WeavingException(_log.QualifyMessage(ex.Message, ex.Instruction))
{
SequencePoint = ex.Instruction.GetInputSequencePoint(_method)
SequencePoint = _sequencePoints.GetInputSequencePoint(ex.Instruction)
};
}
catch (WeavingException ex)
Expand Down Expand Up @@ -62,8 +63,9 @@ private static bool IsAnchorMethodCall(Instruction instruction)
};
}

private void ProcessImpl()
private bool ProcessImpl()
{
var processed = false;
var instruction = Instructions.FirstOrDefault();
Instruction? nextInstruction;

Expand All @@ -77,6 +79,7 @@ private void ProcessImpl()
try
{
nextInstruction = ProcessAnchorMethod(instruction);
processed = true;
}
catch (InstructionWeavingException)
{
Expand All @@ -91,6 +94,7 @@ private void ProcessImpl()
throw new InstructionWeavingException(instruction, $"Unexpected error occured while processing method {_method.FullName} at instruction {instruction}: {ex}");
}
}
return processed;
}

private Instruction? ProcessAnchorMethod(Instruction instruction)
Expand Down
75 changes: 37 additions & 38 deletions src/InterfaceBaseInvoke.Fody/Processing/References.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
namespace InterfaceBaseInvoke.Fody.Processing
namespace InterfaceBaseInvoke.Fody.Processing;

public sealed class References
{
public sealed class References
{
public TypeReferences Types { get; }
public MethodReferences Methods { get; }
public TypeReferences Types { get; }
public MethodReferences Methods { get; }

public References(ModuleDefinition module)
{
Types = new TypeReferences(module);
Methods = new MethodReferences(module, Types);
}
public References(ModuleWeavingContext context)
{
Types = new TypeReferences(context);
Methods = new MethodReferences(context, Types);
}
}

public sealed class TypeReferences
{
public TypeReference RuntimeMethodHandle { get; }
public TypeReference IntPtr { get; }
public TypeReference Int32 { get; }
public TypeReference Environment { get; }
public TypeReference Boolean { get; }
public sealed class TypeReferences
{
public TypeReference RuntimeMethodHandle { get; }
public TypeReference IntPtr { get; }
public TypeReference Int32 { get; }
public TypeReference Environment { get; }
public TypeReference Boolean { get; }

public TypeReferences(ModuleDefinition module)
{
Environment = module.ImportReference(typeof(Environment));
IntPtr = module.ImportReference(typeof(IntPtr));
Int32 = module.ImportReference(typeof(int));
RuntimeMethodHandle = module.ImportReference(typeof(RuntimeMethodHandle));
Boolean = module.ImportReference(typeof(bool));
}
public TypeReferences(ModuleWeavingContext context)
{
Environment = context.ImportReference(typeof(Environment));
IntPtr = context.ImportReference(typeof(IntPtr));
Int32 = context.ImportReference(typeof(int));
RuntimeMethodHandle = context.ImportReference(typeof(RuntimeMethodHandle));
Boolean = context.ImportReference(typeof(bool));
}
}

public sealed class MethodReferences
{
public MethodReference FunctionPointer { get; }
public MethodReference ToInt32 { get; }
public MethodReference ToInt64 { get; }
public MethodReference Is64BitProcess { get; }
public sealed class MethodReferences
{
public MethodReference FunctionPointer { get; }
public MethodReference ToInt32 { get; }
public MethodReference ToInt64 { get; }
public MethodReference Is64BitProcess { get; }

public MethodReferences(ModuleDefinition module, TypeReferences types)
{
FunctionPointer = MethodRefBuilder.MethodByNameAndSignature(module, types.RuntimeMethodHandle, nameof(RuntimeMethodHandle.GetFunctionPointer), 0, types.IntPtr, Enumerable.Empty<TypeReference>()).Build();
ToInt32 = MethodRefBuilder.MethodByName(module, types.IntPtr, nameof(IntPtr.ToInt32)).Build();
ToInt64 = MethodRefBuilder.MethodByName(module, types.IntPtr, nameof(IntPtr.ToInt64)).Build();
Is64BitProcess = MethodRefBuilder.PropertyGet(module, types.Environment, nameof(Environment.Is64BitProcess)).Build();
}
public MethodReferences(ModuleWeavingContext context, TypeReferences types)
{
FunctionPointer = MethodRefBuilder.MethodByNameAndSignature(context, types.RuntimeMethodHandle, nameof(RuntimeMethodHandle.GetFunctionPointer), 0, types.IntPtr.ToTypeRefBuilder(context), []).Build();
ToInt32 = MethodRefBuilder.MethodByName(context, types.IntPtr, nameof(IntPtr.ToInt32)).Build();
ToInt64 = MethodRefBuilder.MethodByName(context, types.IntPtr, nameof(IntPtr.ToInt64)).Build();
Is64BitProcess = MethodRefBuilder.PropertyGet(context, types.Environment, nameof(Environment.Is64BitProcess)).Build();
}
}
5 changes: 2 additions & 3 deletions src/InterfaceBaseInvoke/InterfaceBaseInvoke.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
<PackageId>InterfaceBaseInvoke.Fody</PackageId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Fody" Version="6.8.0" PrivateAssets="none" />
<PackageReference Include="FodyPackaging" Version="6.8.0" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.8.2" PrivateAssets="none" />
<PackageReference Include="FodyPackaging" Version="6.8.2" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\InterfaceBaseInvoke.Fody\InterfaceBaseInvoke.Fody.csproj" PrivateAssets="All" />
</ItemGroup>

<Import Project="..\MoreFodyHelpers.props" />

</Project>
2 changes: 2 additions & 0 deletions src/InterfaceBaseInvoke/ObjectExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.CompilerServices;

namespace InterfaceBaseInvoke;

Expand All @@ -13,6 +14,7 @@ public static class ObjectExtension
/// <typeparam name="TInterface"></typeparam>
/// <param name="instance"></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.NoInlining)]
public static TInterface Base<TInterface>(this TInterface instance) =>
throw new InvalidOperationException("This method is meant to be replaced at compile time by InterfaceBaseInvoke.Fody, but the weaver has not been executed correctly.");
}
Loading

0 comments on commit 5c47006

Please sign in to comment.