Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Tracer.Fody.Tests/Filters/DefaultFilter/DefaultFilterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,34 @@ private void MyMethod()
filter.ShouldAddTrace(methodDef).ShouldTrace.Should().BeTrue();
}

[Test]
public void MethodLevelTraceOn_Overrides_AssemblyLevel_VirtualMethod()
{
string code = @"
using TracerAttributes;

namespace First
{
public class MyDerivedClass : MyClass
{
protected override void MyMethod()
{}
}

public class MyClass
{
[TraceOn]
protected virtual void MyMethod()
{}
}
}
";

var methodDef = GetMethodDefinition(code, "MyDerivedClass", "MyMethod");
var filter = GetDefaultFilter(TraceTargetVisibility.Public, TraceTargetVisibility.Public);
filter.ShouldAddTrace(methodDef).ShouldTrace.Should().BeTrue();
}

[Test]
public void MethodLevelTraceOn_Overrides_ClassLevel()
{
Expand Down
12 changes: 12 additions & 0 deletions Tracer.Fody.Tests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,18 @@ protected MockLogResult RunCode(string assemblyPath, string entryClass, string e
}
}

protected MethodDefinition GetMethodDefinition(string source, string className, string methodName)
{
var testDllLocation = new Uri(Assembly.GetExecutingAssembly().CodeBase);
var assemblyPath = Compile(source, "testasm", new[] { testDllLocation.AbsolutePath });

using (var moduleDef = ModuleDefinition.ReadModule(assemblyPath))
{
return moduleDef.GetAllTypes().Where(typeDef => typeDef.Name == className).SelectMany(typeDef => typeDef.Methods)
.FirstOrDefault(methodDef => methodDef.Name.Equals(methodName, StringComparison.OrdinalIgnoreCase));
}
}

protected MethodDefinition GetMethodDefinition(string source, string methodName)
{
var testDllLocation = new Uri(Assembly.GetExecutingAssembly().CodeBase);
Expand Down
35 changes: 22 additions & 13 deletions Tracer.Fody/Filters/TraceAttributeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,33 @@ public class TraceAttributeHelper

public FilterResult? ShouldTraceBasedOnMethodLevelInfo(MethodDefinition definition)
{
if (!definition.IsPropertyAccessor())
while (true)
{
if (definition.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.TraceOn", StringComparison.Ordinal)))
return new FilterResult(true, GetTraceOnAttributeParameters(definition));
if (definition.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.NoTrace", StringComparison.Ordinal)))
return new FilterResult(false);
}
else
{ //its a property accessor check the prop for the attribute
var correspondingProp =
definition.DeclaringType.Properties.FirstOrDefault(prop => prop.GetMethod == definition || prop.SetMethod == definition);
if (correspondingProp != null)
if (!definition.IsPropertyAccessor())
{
if (correspondingProp.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.TraceOn", StringComparison.Ordinal)))
if (definition.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.TraceOn", StringComparison.Ordinal)))
return new FilterResult(true, GetTraceOnAttributeParameters(definition));
if (correspondingProp.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.NoTrace", StringComparison.Ordinal)))
if (definition.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.NoTrace", StringComparison.Ordinal)))
return new FilterResult(false);
}
else
{ //its a property accessor check the prop for the attribute
var correspondingProp =
definition.DeclaringType.Properties.FirstOrDefault(prop => prop.GetMethod == definition || prop.SetMethod == definition);
if (correspondingProp != null)
{
if (correspondingProp.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.TraceOn", StringComparison.Ordinal)))
return new FilterResult(true, GetTraceOnAttributeParameters(definition));
if (correspondingProp.CustomAttributes.Any(attr => attr.AttributeType.FullName.Equals("TracerAttributes.NoTrace", StringComparison.Ordinal)))
return new FilterResult(false);
}
}

MethodDefinition baseDefinition = Mono.Cecil.Rocks.MethodDefinitionRocks.GetBaseMethod(definition);
if (baseDefinition == definition)
break;

definition = baseDefinition;
}

return null;
Expand Down