Skip to content

Commit 43336ee

Browse files
Fix type reference name in attribute argument getting mangled when such attribute is put on a method in a projected type. (#722)
Co-authored-by: Tautvydas Žilys <[email protected]>
1 parent 1b1b58a commit 43336ee

File tree

5 files changed

+42
-3
lines changed

5 files changed

+42
-3
lines changed

Mono.Cecil/AssemblyWriter.cs

+22-1
Original file line numberDiff line numberDiff line change
@@ -2988,7 +2988,7 @@ void WriteCustomAttributeValue (TypeReference type, object value)
29882988
break;
29892989
case ElementType.None:
29902990
if (type.IsTypeOf ("System", "Type"))
2991-
WriteTypeReference ((TypeReference) value);
2991+
WriteCustomAttributeTypeValue ((TypeReference) value);
29922992
else
29932993
WriteCustomAttributeEnumValue (type, value);
29942994
break;
@@ -2998,6 +2998,27 @@ void WriteCustomAttributeValue (TypeReference type, object value)
29982998
}
29992999
}
30003000

3001+
private void WriteCustomAttributeTypeValue (TypeReference value)
3002+
{
3003+
var typeDefinition = value as TypeDefinition;
3004+
3005+
if (typeDefinition != null) {
3006+
TypeDefinition outermostDeclaringType = typeDefinition;
3007+
while (outermostDeclaringType.DeclaringType != null)
3008+
outermostDeclaringType = outermostDeclaringType.DeclaringType;
3009+
3010+
// In CLR .winmd files, custom attribute arguments reference unmangled type names (rather than <CLR>Name)
3011+
if (WindowsRuntimeProjections.IsClrImplementationType (outermostDeclaringType)) {
3012+
WindowsRuntimeProjections.Project (outermostDeclaringType);
3013+
WriteTypeReference (value);
3014+
WindowsRuntimeProjections.RemoveProjection (outermostDeclaringType);
3015+
return;
3016+
}
3017+
}
3018+
3019+
WriteTypeReference (value);
3020+
}
3021+
30013022
void WritePrimitiveValue (object value)
30023023
{
30033024
if (value == null)

Mono.Cecil/WindowsRuntimeProjections.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ static bool NeedsWindowsRuntimePrefix (TypeDefinition type)
389389
return true;
390390
}
391391

392-
static bool IsClrImplementationType (TypeDefinition type)
392+
public static bool IsClrImplementationType (TypeDefinition type)
393393
{
394394
if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.SpecialName)) != TypeAttributes.SpecialName)
395395
return false;

Test/Mono.Cecil.Tests/TypeParserTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public void ByRefTypeReference ()
8888
public void FullyQualifiedTypeReference ()
8989
{
9090
var module = GetCurrentModule ();
91-
var cecil = module.AssemblyReferences.Where (reference => reference.Name == "Mono.Cecil").First ();
91+
var cecil = module.AssemblyReferences.Where (reference => reference.Name != typeof (TypeDefinition).Assembly.GetName ().Name).First ();
9292

9393
var fullname = "Mono.Cecil.TypeDefinition, " + cecil.FullName;
9494

Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs

+18
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@ public void CanProjectClasses ()
131131
Assert.AreEqual (TypeDefinitionTreatment.PrefixWindowsRuntimeName, winrtSomeOtherClassType.WindowsRuntimeProjection.Treatment);
132132
}, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (), applyWindowsRuntimeProjections: true);
133133
}
134+
135+
[Test]
136+
public void VerifyTypeReferenceToProjectedTypeInAttributeArgumentReferencesUnmangledTypeName()
137+
{
138+
if (Platform.OnMono)
139+
return;
140+
141+
TestModule(ModuleName, (module) =>
142+
{
143+
var type = module.Types.Single(t => t.Name == "ClassWithAsyncMethod");
144+
var method = type.Methods.Single(m => m.Name == "DoStuffAsync");
145+
146+
var attribute = method.CustomAttributes.Single(a => a.AttributeType.Name == "AsyncStateMachineAttribute");
147+
var attributeArgument = (TypeReference)attribute.ConstructorArguments[0].Value;
148+
149+
Assert.AreEqual("ManagedWinmd.ClassWithAsyncMethod/<DoStuffAsync>d__0", attributeArgument.FullName);
150+
}, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance(), applyWindowsRuntimeProjections: true);
151+
}
134152
}
135153

136154
[TestFixture]
1.5 KB
Binary file not shown.

0 commit comments

Comments
 (0)