diff --git a/Cecilifier.Core.Tests/TestResources/Integration/Generics/UsageOfNonGenericMethodOnGenericType.cs.txt b/Cecilifier.Core.Tests/TestResources/Integration/Generics/UsageOfNonGenericMethodOnGenericType.cs.txt new file mode 100644 index 00000000..2ed2a761 --- /dev/null +++ b/Cecilifier.Core.Tests/TestResources/Integration/Generics/UsageOfNonGenericMethodOnGenericType.cs.txt @@ -0,0 +1,10 @@ +using System; +class C +{ + public void Method(T t) {} +} + +class UsageOfNonGenericMethodOnGenericType +{ + void M(C c) => c.Method(42); +} diff --git a/Cecilifier.Core.Tests/TestResources/Integration/Types/AttributeGeneric.cs.txt b/Cecilifier.Core.Tests/TestResources/Integration/Types/AttributeGeneric.cs.txt index d0c66a5b..c7833ba9 100644 --- a/Cecilifier.Core.Tests/TestResources/Integration/Types/AttributeGeneric.cs.txt +++ b/Cecilifier.Core.Tests/TestResources/Integration/Types/AttributeGeneric.cs.txt @@ -6,9 +6,10 @@ class MyGenericAttribute : System.Attribute public T Value {get; set; } } -/* [MyGeneric] +[MyGeneric(42)] [MyGeneric("gen-attr-value")] [MyGeneric(Value = true)] -class Foo {} -*/ \ No newline at end of file +[MyGeneric(true)] +[MyGeneric("str", Value="Other str")] +class Foo {} \ No newline at end of file diff --git a/Cecilifier.Core.Tests/Tests/Integration/GenericsTestCase.cs b/Cecilifier.Core.Tests/Tests/Integration/GenericsTestCase.cs index a990e6fc..4fae26e9 100644 --- a/Cecilifier.Core.Tests/Tests/Integration/GenericsTestCase.cs +++ b/Cecilifier.Core.Tests/Tests/Integration/GenericsTestCase.cs @@ -93,5 +93,11 @@ public void TestCoContraVariance() { AssertResourceTest(@"Generics/CoContraVariance"); } + + [Test] + public void TestUsageOfNonGenericMethodOnGenericType() + { + AssertResourceTest("Generics/UsageOfNonGenericMethodOnGenericType"); + } } } diff --git a/Cecilifier.Core.Tests/Tests/Unit/AttributesTest.cs b/Cecilifier.Core.Tests/Tests/Unit/AttributesTest.cs index 7b8106df..2aae4976 100644 --- a/Cecilifier.Core.Tests/Tests/Unit/AttributesTest.cs +++ b/Cecilifier.Core.Tests/Tests/Unit/AttributesTest.cs @@ -49,6 +49,25 @@ public void TestGenericAttributeDefinition() @"\s+.+(gp_T_\d+) = new Mono.Cecil.GenericParameter\(""T"", \1\);" + @"\s+.+\1.GenericParameters.Add\(\2\);")); } + + [TestCase("[MyGeneric]", "Int32", TestName="Value Type")] + [TestCase("[MyGeneric]", "String", TestName = "Reference Type")] + [TestCase("[MyGeneric>]", @"cls_foo_\d+.MakeGenericInstanceType\(.+Int32\)", TestName = "Generic Type")] + public void TestGenericAttributeUsage(string attribute, string expectedType) + { + var result = RunCecilifier($@" +{GenericAttributeDefinition} + +{attribute} +class Foo {{ }}"); + + var cecilifiedCode = result.GeneratedCode.ReadToEnd(); + Assert.That( + cecilifiedCode, + Does.Match( + $@"(?s)var (attr_myGeneric_1_\d+) = new CustomAttribute\(new MethodReference\((ctor_myGenericAttribute_\d+)\.Name.+\2\.ReturnType\).+DeclaringType = cls_myGenericAttribute_\d+.MakeGenericInstanceType\(.*{expectedType}\).+\);\s+" + + @"cls_foo_\d+\.CustomAttributes\.Add\(\1\);")); + } private const string AttributeDefinition = "class MyAttribute : System.Attribute { public MyAttribute(string message) {} } "; private const string GenericAttributeDefinition = @" diff --git a/Cecilifier.Core/AST/SyntaxWalkerBase.cs b/Cecilifier.Core/AST/SyntaxWalkerBase.cs index 98ee63a4..7dfb0e92 100644 --- a/Cecilifier.Core/AST/SyntaxWalkerBase.cs +++ b/Cecilifier.Core/AST/SyntaxWalkerBase.cs @@ -822,11 +822,7 @@ private static IEnumerable ProcessNormalMemberAttribute(IVisitorContext // Attribute is defined in the same assembly. We need to find the variable that holds its "ctor declaration" var attrCtor = attrType.GetMembers().OfType().SingleOrDefault(m => m.MethodKind == MethodKind.Constructor && m.Parameters.Length == attrArgs.Length); EnsureForwardedMethod(context, context.Naming.SyntheticVariable(attribute.Name.ValueText().AttributeName(), ElementKind.Constructor), attrCtor, Array.Empty()); - var attrCtorVar = context.DefinitionVariables.GetMethodVariable(attrCtor.AsMethodDefinitionVariable()); - if (!attrCtorVar.IsValid) - throw new Exception($"Could not find variable for {attrCtor.ContainingType.Name} ctor."); - - return attrCtorVar.VariableName; + return attrCtor.MethodResolverExpression(context); }); return attrsExp; diff --git a/Cecilifier.Core/Misc/NameSyntaxExtensions.cs b/Cecilifier.Core/Misc/NameSyntaxExtensions.cs index f304fed5..d6cd2913 100644 --- a/Cecilifier.Core/Misc/NameSyntaxExtensions.cs +++ b/Cecilifier.Core/Misc/NameSyntaxExtensions.cs @@ -22,5 +22,10 @@ public class SimpleNameExtractor : CSharpSyntaxVisitor { return node.Identifier.Text; } + + public override string VisitGenericName(GenericNameSyntax node) + { + return $"{node.Identifier.Text}_{node.Arity}"; + } } }