Skip to content

Commit

Permalink
add error for incorrect attribute usage
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonCropp committed Feb 2, 2020
1 parent 2524d8e commit 6da330e
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 16 deletions.
11 changes: 11 additions & 0 deletions AssemblyToProcess/PropertyAttribuesWithNoEquals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class PropertyAttributesWithNoEquals
{
[IgnoreDuringEquals]
public int Property { get; set; }

[CustomEqualsInternal]
[CustomGetHashCode]
public void Method()
{
}
}
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<PropertyGroup>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>latest</LangVersion>
<Version>4.0.0</Version>
<Version>4.0.1</Version>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion Equals.Fody/Equals.Fody.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
<DebugType>portable</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FodyHelpers" Version="6.0.8" />
<PackageReference Include="FodyHelpers" Version="6.1.0" />
</ItemGroup>
</Project>
4 changes: 2 additions & 2 deletions Equals.Fody/Injectors/EqualsInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public MethodReference InjectEqualsInternal(TypeDefinition type, TypeReference t
body.InitLocals = true;
var ins = body.Instructions;

var properties = type.GetPropertiesWithoutIgnores(ignoreAttributeName);
var properties = type.GetPropertiesWithoutIgnores(ignoreDuringEqualsAttributeName);
if (ignoreBaseClassProperties)
{
properties = properties.IgnoreBaseClassProperties(type);
Expand All @@ -102,7 +102,7 @@ public MethodReference InjectEqualsInternal(TypeDefinition type, TypeReference t

var methods = type.GetMethods();
var customLogic = methods
.Where(x => x.CustomAttributes.Any(y => y.AttributeType.Name == customEqualsAttribute)).ToArray();
.Where(x => x.CustomAttributes.Any(y => y.AttributeType.Name == customEqualsInternalAttribute)).ToArray();

if (customLogic.Length > 2)
{
Expand Down
2 changes: 1 addition & 1 deletion Equals.Fody/Injectors/GetHashCodeInjector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void InjectGetHashCode(TypeDefinition type, bool ignoreBaseClassPropertie
ins.Add(Instruction.Create(OpCodes.Ldc_I4_0));
ins.Add(Instruction.Create(OpCodes.Stloc, resultVariable));

var properties = ModuleDefinition.ImportReference(type).Resolve().GetPropertiesWithoutIgnores(ignoreAttributeName);
var properties = ModuleDefinition.ImportReference(type).Resolve().GetPropertiesWithoutIgnores(ignoreDuringEqualsAttributeName);
if (ignoreBaseClassProperties)
{
properties = properties.IgnoreBaseClassProperties(type);
Expand Down
44 changes: 37 additions & 7 deletions Equals.Fody/ModuleWeaver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ public partial class ModuleWeaver :
BaseModuleWeaver
{
public const string attributeName = "EqualsAttribute";
public const string ignoreAttributeName = "IgnoreDuringEqualsAttribute";
public const string customEqualsAttribute = "CustomEqualsInternalAttribute";
public const string ignoreDuringEqualsAttributeName = "IgnoreDuringEqualsAttribute";
public const string customEqualsInternalAttribute = "CustomEqualsInternalAttribute";

public const string DoNotAddEqualityOperators = "DoNotAddEqualityOperators";
public const string DoNotAddGetHashCode = "DoNotAddGetHashCode";
Expand All @@ -35,9 +35,9 @@ TypeReference GetGenericType(TypeReference type)

public override void Execute()
{
if (!FindReferencesAndDetermineWhetherEqualsIsReferenced(FindType))
if (!FindReferencesAndDetermineWhetherEqualsIsReferenced(FindTypeDefinition))
{
LogDebug("Assembly does not reference 'Equals' assembly. No work to do - exiting.");
WriteDebug("Assembly does not reference 'Equals' assembly. No work to do - exiting.");
return;
}

Expand Down Expand Up @@ -97,6 +97,36 @@ public override void Execute()
{
RemoveFodyAttributes(type);
}

CheckForInvalidAttributes();
}

void CheckForInvalidAttributes()
{
foreach (var type in ModuleDefinition.GetTypes())
{
foreach (var method in type.Methods)
{
if (method.CustomAttributes.Any(x => x.AttributeType.Name == customEqualsInternalAttribute))
{
WriteError($"Method `{type.FullName}.{method.Name}` contains {customEqualsInternalAttribute} but has no `[Equals]` attribute.", method);
}

if (method.CustomAttributes.Any(x => x.AttributeType.Name == CustomGetHashCodeAttribute))
{
WriteError($"Method `{type.FullName}.{method.Name}` contains {CustomGetHashCodeAttribute} but has no `[Equals]` attribute.", method);
}
}

foreach (var property in type.Properties)
{
if (property.CustomAttributes.Any(x => x.AttributeType.Name == ignoreDuringEqualsAttributeName))
{
//TODO: add sequence point
WriteError($"Property `{type.FullName}.{property.Name}` contains {ignoreDuringEqualsAttributeName} but has no `[Equals]` attribute.");
}
}
}
}

public override IEnumerable<string> GetAssembliesForScanning()
Expand Down Expand Up @@ -128,17 +158,17 @@ void RemoveFodyAttributes(TypeDefinition type)

foreach (var property in type.Properties)
{
property.RemoveAttribute(ignoreAttributeName);
property.RemoveAttribute(ignoreDuringEqualsAttributeName);
}

foreach (var property in type.Fields)
{
property.RemoveAttribute(ignoreAttributeName);
property.RemoveAttribute(ignoreDuringEqualsAttributeName);
}

foreach (var method in type.Methods)
{
method.RemoveAttribute(customEqualsAttribute);
method.RemoveAttribute(customEqualsInternalAttribute);
method.RemoveAttribute(CustomGetHashCodeAttribute);
}
}
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions Equals/Equals.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<PackageTags>Equals, GetHashCode, ILWeaving, Fody, Cecil</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Fody" Version="6.0.8" PrivateAssets="none" />
<PackageReference Include="FodyPackaging" Version="6.0.8" PrivateAssets="All" />
<PackageReference Include="Fody" Version="6.1.0" PrivateAssets="none" />
<PackageReference Include="FodyPackaging" Version="6.1.0" PrivateAssets="All" />
</ItemGroup>
</Project>
5 changes: 5 additions & 0 deletions Tests/IntegrationTests.IncorrectAttributes.verified.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
'Method `PropertyAttributesWithNoEquals.Method` contains CustomEqualsInternalAttribute but has no `[Equals]` attribute.',
'Method `PropertyAttributesWithNoEquals.Method` contains CustomGetHashCodeAttribute but has no `[Equals]` attribute.',
'Property `PropertyAttributesWithNoEquals.Property` contains IgnoreDuringEqualsAttribute but has no `[Equals]` attribute.'
]
7 changes: 7 additions & 0 deletions Tests/IntegrationTests_operators.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Xunit;

public partial class IntegrationTests
Expand Down Expand Up @@ -135,6 +136,12 @@ public void Equality_operator_should_return_true_for_equal_object_collections()
Assert.False(first != second);
}

[Fact]
public Task IncorrectAttributes()
{
return Verify(testResult.Errors.Select(x => x.Text));
}

[Fact]
public void Equality_operator_should_return_false_for_collections_with_different_size()
{
Expand Down
4 changes: 2 additions & 2 deletions Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<PackageReference Include="FodyHelpers" Version="6.0.8" />
<PackageReference Include="FodyHelpers" Version="6.1.0" />
<PackageReference Include="Xunit" Version="2.4.1" />
<PackageReference Include="XunitContext" Version="1.8.0" />
<PackageReference Include="Verify.Xunit" Version="1.13.0" />
<PackageReference Include="Verify.Xunit" Version="1.14.1" />
<ProjectReference Include="..\BadCaseAssembliesToProcess\ClassWithOperatorsOptOutButWeavingInstruction\ClassWithOperatorsOptOutButWeavingInstruction.csproj" />
<ProjectReference Include="..\BadCaseAssembliesToProcess\ClassWithoutOperators\ClassWithoutOperators.csproj" />
<ProjectReference Include="..\BadCaseAssembliesToProcess\ClassWithoutWeavingInstruction\ClassWithoutWeavingInstruction.csproj" />
Expand Down

0 comments on commit 6da330e

Please sign in to comment.