Skip to content

Commit

Permalink
Handle more Attribute Types when Filtering Assemblies
Browse files Browse the repository at this point in the history
Fixes #9369

When System.Reflection.Metadata comes across an Attribute
which has a generic, it does NOT return a `TypeReferenceHandle`.
It returns a `TypeSpecificationHandle`.

Tying to cast the type results in the following error

```
System.InvalidCastException: Die angegebene Umwandlung ist ungültig.
error XAFLT7007:    bei System.Reflection.Throw.InvalidCast()
error XAFLT7007:    bei System.Reflection.Metadata.TypeReferenceHandle.op_Explicit(EntityHandle handle)
error XAFLT7007:    bei Xamarin.Android.Tasks.MetadataExtensions.GetCustomAttributeFullName(MetadataReader reader, CustomAttribute attribute)
error XAFLT7007:    bei Xamarin.Android.Tasks.FilterAssemblies.IsAndroidAssembly(AssemblyDefinition assembly, MetadataReader reader)
error XAFLT7007:    bei Xamarin.Android.Tasks.FilterAssemblies.ProcessAssembly(ITaskItem assemblyItem, List`1 output)
error XAFLT7007:    bei Xamarin.Android.Tasks.FilterAssemblies.RunTask()
error XAFLT7007:    bei Microsoft.Android.Build.Tasks.AndroidTask.Execute()
```

So we need to handle this case, and put in place a backup to handle
an `InvalidCastException` so that we never hit this issue again.
  • Loading branch information
dellis1972 committed Oct 7, 2024
1 parent 4e4bc08 commit 3be2474
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
4 changes: 4 additions & 0 deletions samples/HelloWorld/HelloLibrary/LibraryActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
using Android.Views;
using Android.Widget;

[assembly: HelloLibrary.GenericTest<string>]
namespace HelloLibrary
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public class GenericTestAttribute<T> : Attribute { }

[Activity(Label = "Library Activity", Name="mono.samples.hello.LibraryActivity")]
public class LibraryActivity : Activity
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1461,5 +1461,48 @@ public void BuildWithJavaToolOptions ()
Environment.SetEnvironmentVariable ("JAVA_TOOL_OPTIONS", oldEnvVar);
}
}

[Test]
public void LibraryWithGenericAttribute ()
{
var path = Path.Combine ("temp", TestContext.CurrentContext.Test.Name);
var lib = new XamarinAndroidLibraryProject {
ProjectName = "Library1",
IsRelease = true,
Sources = {
new BuildItem.Source ("Class1.cs") {
TextContent = () => """
namespace Library1;
public class Class1 { }
"""
},
new BuildItem.Source ("GenericTestAttribute.cs") {
TextContent = () => """
using System;
[assembly: GenericTestAttribute<Guid>]
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)]
public class GenericTestAttribute<T> : Attribute { }
""",
},
},
};
var proj = new XamarinAndroidApplicationProject {
ProjectName = "App1",
IsRelease = true,
Sources = {
new BuildItem.Source ("Class2.cs") {
TextContent= () => """
namespace App1;
class Class2 : Library1.Class1 { }
""",
},
},
};
proj.AddReference (lib);
using var libb = CreateDllBuilder (Path.Combine (path, "Library1"));
Assert.IsTrue (libb.Build (lib), "Library1 Build should have succeeded.");
using var b = CreateApkBuilder (Path.Combine (path, "App1"));
Assert.IsTrue (b.Build (proj), "App1 Build should have succeeded.");
}
}
}
19 changes: 17 additions & 2 deletions src/Xamarin.Android.Build.Tasks/Utilities/MetadataExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,23 @@ public static string GetCustomAttributeFullName (this MetadataReader reader, Cus
{
if (attribute.Constructor.Kind == HandleKind.MemberReference) {
var ctor = reader.GetMemberReference ((MemberReferenceHandle)attribute.Constructor);
var type = reader.GetTypeReference ((TypeReferenceHandle)ctor.Parent);
return reader.GetString (type.Namespace) + "." + reader.GetString (type.Name);
try {
if (ctor.Parent.Kind == HandleKind.TypeReference) {
var type = reader.GetTypeReference ((TypeReferenceHandle)ctor.Parent);
return reader.GetString (type.Namespace) + "." + reader.GetString (type.Name);
} else if (ctor.Parent.Kind == HandleKind.TypeSpecification) {
var type = reader.GetTypeSpecification ((TypeSpecificationHandle)ctor.Parent);
BlobReader blobReader = reader.GetBlobReader (type.Signature);
SignatureTypeCode typeCode = blobReader.ReadSignatureTypeCode ();
EntityHandle typeHandle = blobReader.ReadTypeHandle ();
TypeReference typeRef = reader.GetTypeReference ((TypeReferenceHandle)typeHandle);
return reader.GetString (typeRef.Namespace) + "." + reader.GetString (typeRef.Name);
}
}
catch (InvalidCastException)
{
return null;
}
} else if (attribute.Constructor.Kind == HandleKind.MethodDefinition) {
var ctor = reader.GetMethodDefinition ((MethodDefinitionHandle)attribute.Constructor);
var type = reader.GetTypeDefinition (ctor.GetDeclaringType ());
Expand Down

0 comments on commit 3be2474

Please sign in to comment.