Skip to content

Commit

Permalink
fix(ClearProperty): don't inject into existing method
Browse files Browse the repository at this point in the history
Existing methods most likely already handle clearing the property in
a different way compared to just setting it to null. This fix allows
to override the behavior by implementing the method manually.

BREAKING CHANGE: The ClearPropertyMethod weaver no longer injects
anything into the Clear method in case it already exists. An info
logging statement has been added that can help to find the Clear
method implementations and ensure it clears the property manually.
  • Loading branch information
Christopher-Marcel Böddecker committed Jan 11, 2019
1 parent 79f9f7c commit b52819d
Showing 1 changed file with 22 additions and 20 deletions.
42 changes: 22 additions & 20 deletions Sources/ClearPropertyMethod.Fody/ModuleWeaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,19 @@ public override void Execute()

foreach (PropertyDefinition propertyDefinition in propertyDefinitions)
{
MethodDefinition clearMethodDefinition =
FindOrCreateClearMethod(propertyDefinition, clearMethodNamePrefix);
clearMethodDefinition.IsPublic = true;

string methodName = clearMethodNamePrefix
+ char.ToUpperInvariant(propertyDefinition.Name[0])
+ propertyDefinition.Name.Substring(1);
MethodDefinition existingMethodDefinition = FindClearMethod(propertyDefinition, methodName);
if (existingMethodDefinition != null)
{
LogInfo(
$"The clear method '{existingMethodDefinition.FullName}' already exists."
+ $" A setter call to clear the property '{propertyDefinition.FullName}' will not be inserted.");
continue;
}

MethodDefinition clearMethodDefinition = CreateClearMethod(propertyDefinition, methodName);
ClearPropertyInMethod(propertyDefinition, clearMethodDefinition);
}
}
Expand All @@ -61,28 +70,21 @@ private IEnumerable<Regex> FindNamespaceFilters() =>
.ToList()
?? Enumerable.Empty<Regex>();

private MethodDefinition FindOrCreateClearMethod(
IMemberDefinition propertyDefinition,
string clearMethodNamePrefix)
{
string methodName = clearMethodNamePrefix
+ char.ToUpperInvariant(propertyDefinition.Name[0])
+ propertyDefinition.Name.Substring(1);
TypeReference returnTypeReference = TypeSystem.VoidReference;

MethodDefinition existingMethodDefinition = propertyDefinition.DeclaringType.Methods.FirstOrDefault(
private MethodDefinition FindClearMethod(IMemberDefinition propertyDefinition, string methodName) =>
propertyDefinition.DeclaringType.Methods.FirstOrDefault(
definition => string.Equals(definition.Name, methodName, StringComparison.OrdinalIgnoreCase)
&& definition.ReturnType.FullName == returnTypeReference.FullName
&& definition.ReturnType.FullName == TypeSystem.VoidReference.FullName
&& !definition.HasParameters);
if (existingMethodDefinition != null)
{
return existingMethodDefinition;
}

private MethodDefinition CreateClearMethod(IMemberDefinition propertyDefinition, string methodName)
{
MethodDefinition newMethodDefinition = new MethodDefinition(
methodName,
MethodAttributes.Public | MethodAttributes.HideBySig,
returnTypeReference);
TypeSystem.VoidReference)
{
IsPublic = true
};
newMethodDefinition.CustomAttributes.Add(
new CustomAttribute(_compilerGeneratedAttributeConstructorReference));
propertyDefinition.DeclaringType.Methods.Add(newMethodDefinition);
Expand Down

0 comments on commit b52819d

Please sign in to comment.