Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
vitkuz573 committed May 4, 2024
1 parent 25d6cd3 commit 062625d
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 40 deletions.
28 changes: 11 additions & 17 deletions PrismCommands.Fody/ConstructorCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,24 @@
/// <summary>
/// Represents a cache for constructors used during the weaving process.
/// </summary>
public class ConstructorCache
/// <remarks>
/// Initializes a new instance of the <see cref="ConstructorCache"/> class.
/// </remarks>
/// <param name="moduleDefinition">The module definition to be used in the constructor cache.</param>
public class ConstructorCache(ModuleDefinition moduleDefinition)
{
private readonly Dictionary<bool, MethodDefinition> _delegateCommandConstructors;
private readonly ModuleDefinition _moduleDefinition;
private readonly Dictionary<bool, MethodDefinition> _delegateCommandConstructors = [];

private MethodReference _actionConstructor;
private MethodReference _funcConstructor;

/// <summary>
/// Initializes a new instance of the <see cref="ConstructorCache"/> class.
/// </summary>
/// <param name="moduleDefinition">The module definition to be used in the constructor cache.</param>
public ConstructorCache(ModuleDefinition moduleDefinition)
{
_delegateCommandConstructors = new Dictionary<bool, MethodDefinition>();
_moduleDefinition = moduleDefinition;
}

/// <summary>
/// Gets the Action constructor reference.
/// </summary>
/// <returns>The Action constructor reference.</returns>
public MethodReference GetActionConstructor()
{
return _actionConstructor ??= FindActionConstructor(_moduleDefinition);
return _actionConstructor ??= FindActionConstructor(moduleDefinition);
}

/// <summary>
Expand All @@ -42,7 +36,7 @@ public MethodReference GetActionConstructor()
/// <returns>The Func constructor reference.</returns>
public MethodReference GetFuncConstructor()
{
return _funcConstructor ??= FindFuncConstructor(_moduleDefinition);
return _funcConstructor ??= FindFuncConstructor(moduleDefinition);
}

/// <summary>
Expand Down Expand Up @@ -70,7 +64,7 @@ public MethodDefinition GetDelegateCommandConstructor(WeaverConfig config, bool
private MethodReference FindActionConstructor(ModuleDefinition moduleDefinition)
{
var actionType = moduleDefinition.ImportReference(typeof(Action).FullName);
var actionConstructorInfo = actionType.Resolve().GetConstructors().FirstOrDefault(c => c.Parameters.Count == 2 && c.Parameters[0].ParameterType.MetadataType == MetadataType.Object && c.Parameters[1].ParameterType.MetadataType == MetadataType.IntPtr) ?? throw new WeavingException($"The required Action constructor with two parameters was not found in the type '{actionType.FullName}'. Ensure that the proper version of the System.Runtime assembly is referenced in your project.");
var actionConstructorInfo = actionType.Resolve().GetConstructors().FirstOrDefault(c => c.Parameters.Count == 2 && c.Parameters[0].ParameterType.MetadataType == MetadataType.Object && c.Parameters[1].ParameterType.MetadataType == MetadataType.IntPtr) ?? throw new WeavingException($"The required constructor was not found in the expected types. Ensure that the proper versions of system assemblies like 'System.Runtime' or 'mscorlib' are referenced in your project.");

return moduleDefinition.ImportReference(actionConstructorInfo);
}
Expand All @@ -85,7 +79,7 @@ private MethodReference FindFuncConstructor(ModuleDefinition moduleDefinition)
var openFuncType = moduleDefinition.ImportReference(typeof(Func<>).FullName);
var boolType = moduleDefinition.TypeSystem.Boolean;
var closedFuncType = openFuncType.MakeGenericInstanceType(boolType);
var openFuncConstructorInfo = openFuncType.Resolve().GetConstructors().FirstOrDefault(c => c.Parameters.Count == 2 && c.Parameters[0].ParameterType.MetadataType == MetadataType.Object && c.Parameters[1].ParameterType.MetadataType == MetadataType.IntPtr) ?? throw new WeavingException($"Unable to find Func<> constructor with two parameters in the type '{openFuncType.FullName}'. Ensure that the proper version of the System.Runtime assembly is referenced in your project.");
var openFuncConstructorInfo = openFuncType.Resolve().GetConstructors().FirstOrDefault(c => c.Parameters.Count == 2 && c.Parameters[0].ParameterType.MetadataType == MetadataType.Object && c.Parameters[1].ParameterType.MetadataType == MetadataType.IntPtr) ?? throw new WeavingException($"The required constructor was not found in the expected types. Ensure that the proper versions of system assemblies like 'System.Runtime' or 'mscorlib' are referenced in your project.");

var closedFuncConstructorInfo = new MethodReference(".ctor", openFuncConstructorInfo.ReturnType, closedFuncType)
{
Expand Down
33 changes: 12 additions & 21 deletions PrismCommands.Fody/DelegateCommandTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,25 @@ namespace PrismCommands.Fody;
/// <summary>
/// Transforms the methods marked with the DelegateCommandAttribute into DelegateCommands.
/// </summary>
public class DelegateCommandTransformer
/// <remarks>
/// Initializes a new instance of the <see cref="DelegateCommandTransformer"/> class.
/// </remarks>
/// <param name="moduleDefinition">The module definition to be used in the configuration.</param>
/// <param name="config">The XML configuration element.</param>
public class DelegateCommandTransformer(ModuleDefinition moduleDefinition, XElement config)
{
private const string CommandBackingFieldNameFormat = "<{0}>k__BackingField";
private const string GetCommandMethodNameFormat = "get_{0}";
private const string CommandMethodNameFormat = "{0}Command";

private readonly WeaverConfig _config;
private readonly ConstructorCache _constructorCache;
private readonly ModuleDefinition _moduleDefinition;
private readonly WeaverConfig _config = new(moduleDefinition, config);
private readonly ConstructorCache _constructorCache = new(moduleDefinition);

/// <summary>
/// Gets the name of the DelegateCommandAttribute.
/// </summary>
public string AttributeName { get; } = "DelegateCommandAttribute";

/// <summary>
/// Initializes a new instance of the <see cref="DelegateCommandTransformer"/> class.
/// </summary>
/// <param name="moduleDefinition">The module definition to be used in the configuration.</param>
/// <param name="config">The XML configuration element.</param>
public DelegateCommandTransformer(ModuleDefinition moduleDefinition, XElement config)
{
_moduleDefinition = moduleDefinition;

_config = new WeaverConfig(moduleDefinition, config);
_constructorCache = new ConstructorCache(moduleDefinition);
}

/// <summary>
/// Transforms the specified method into a DelegateCommand.
/// </summary>
Expand Down Expand Up @@ -95,8 +86,8 @@ private FieldDefinition CreateBackingFieldForCommand(MethodDefinition method)
/// <param name="commandField">The backing field to add attributes to.</param>
private void AddAttributesToBackingField(FieldDefinition commandField)
{
commandField.AddAttribute<CompilerGeneratedAttribute>(_moduleDefinition, "System.Runtime");
commandField.AddAttribute<DebuggerBrowsableAttribute>(_moduleDefinition, "System.Runtime", DebuggerBrowsableState.Never);
commandField.AddAttribute<CompilerGeneratedAttribute>(moduleDefinition);
commandField.AddAttribute<DebuggerBrowsableAttribute>(moduleDefinition, DebuggerBrowsableState.Never);
}

/// <summary>
Expand Down Expand Up @@ -158,7 +149,7 @@ private PropertyDefinition CreateCommandProperty(MethodDefinition method, FieldD
}
};

commandProperty.GetMethod.AddAttribute<CompilerGeneratedAttribute>(_moduleDefinition, "System.Runtime");
commandProperty.GetMethod.AddAttribute<CompilerGeneratedAttribute>(moduleDefinition);

return commandProperty;
}
Expand Down Expand Up @@ -203,7 +194,7 @@ private void UpdateConstructor(TypeDefinition type, MethodDefinition method, Fie

var delegateCommandInstructions = new List<Instruction>
{
Instruction.Create(OpCodes.Newobj, _moduleDefinition.ImportReference(delegateCommandCtor)),
Instruction.Create(OpCodes.Newobj, moduleDefinition.ImportReference(delegateCommandCtor)),
Instruction.Create(OpCodes.Stfld, commandField)
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace PrismCommands.Fody.Extensions;

public static class CustomAttributeProviderExtensions
{
public static void AddAttribute<TAttribute>(this ICustomAttributeProvider provider, ModuleDefinition moduleDefinition, string assemblyName, params object[] constructorArgs) where TAttribute : Attribute
public static void AddAttribute<TAttribute>(this ICustomAttributeProvider provider, ModuleDefinition moduleDefinition, params object[] constructorArgs) where TAttribute : Attribute
{
var attributeType = moduleDefinition.ImportReference(typeof(TAttribute).FullName);
var ctor = attributeType.Resolve().GetConstructors().FirstOrDefault() ?? throw new WeavingException($"Unable to find a constructor for attribute '{attributeType.FullName}'.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static TypeReference ImportReference(this ModuleDefinition moduleDefiniti
}
else
{
string[] possibleAssemblies = new[] { "System.Runtime", "mscorlib" };
string[] possibleAssemblies = ["System.Runtime", "mscorlib"];

foreach (var possibleAssemblyName in possibleAssemblies)
{
Expand Down

0 comments on commit 062625d

Please sign in to comment.