Skip to content

Commit

Permalink
[Microsoft.Android.Sdk.Analysis] fix global types (#9680)
Browse files Browse the repository at this point in the history
Context: https://github.com/dotnet/maui/blob/961863afdf603879cfc92def4aa0c362bdcfcb30/src/TestUtils/src/DeviceTests.Runners.SourceGen/RunnerGenerator.cs#L105

We are seeing the following error in dotnet/maui's tests:

    error DNAA0001: Application class 'MainApplication' does not have an Activation Constructor 'MainApplication(IntPtr handle, JniHandleOwnership transfer)'. 

Note that this is normally a warning, but they have
`$(TreatWarningsAsErrors)` set.

The error (warning) is because they are using
`global::Android.Runtime.JniHandleOwnership` rather than
`Android.Runtime.JniHandleOwnership`. This causes our string
comparisons to fail to we report a false error message.

Rather than using `.ToString()` we should switch over to using
`QualifiedNameSyntax` and `IdentifierNameSyntax` to get the name of
the class. This allows us to remove some string comparisons as we can
now get the name of the class without the full namespace if it has a
`global::` prefix.
  • Loading branch information
dellis1972 authored Jan 14, 2025
1 parent 0475a60 commit 9f5dc78
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,20 @@ private static void AnalyzeClass (SyntaxNodeAnalysisContext context)
var parameters = constructor.ParameterList.Parameters;
if (parameters.Count != 2)
continue;
if (parameters [0].Type.ToString () != "IntPtr")
var type = parameters [0].Type switch {
IdentifierNameSyntax identifierNameSyntax => identifierNameSyntax.Identifier.Text,
QualifiedNameSyntax qualifiedNameSyntax => qualifiedNameSyntax.Right.Identifier.Text,
_ => parameters [0].Type.ToString ()
};
if (type != "IntPtr" && type != "nint")
continue;
var ns = Utilities.GetNamespaceForParameterType (parameters [1], context.SemanticModel);
var type = parameters [1].Type.ToString();
var isJniHandle = (ns == "Android.Runtime") && (type == "JniHandleOwnership") || (type == "Android.Runtime.JniHandleOwnership");
type = parameters [1].Type switch {
IdentifierNameSyntax identifierNameSyntax => identifierNameSyntax.Identifier.Text,
QualifiedNameSyntax qualifiedNameSyntax => qualifiedNameSyntax.Right.Identifier.Text,
_ => parameters [1].Type.ToString ()
};
var isJniHandle = (ns == "Android.Runtime") && (type == "JniHandleOwnership");
if (!isJniHandle)
continue;
foundActivationConstructor = true;
Expand Down
11 changes: 7 additions & 4 deletions src/Microsoft.Android.Sdk.Analysis/Tests/DNAA0001Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,22 @@ public async Task DNAA0001DoesNotShow ()
}

[Test]
[TestCase ("JniHandleOwnership")]
[TestCase ("Android.Runtime.JniHandleOwnership")]
public async Task DNAA0001DoesNotShowForExistingCode (string type)
[TestCase ("IntPtr", "JniHandleOwnership")]
[TestCase ("nint", "Android.Runtime.JniHandleOwnership")]
[TestCase ("global::System.IntPtr", "global::Android.Runtime.JniHandleOwnership")]
[TestCase ("System.IntPtr", "AR.JniHandleOwnership")]
public async Task DNAA0001DoesNotShowForExistingCode (string handle, string type)
{
var test = $@"
using System;
using Android.App;
using Android.Runtime;
using AR = Android.Runtime;
namespace ConsoleApplication1
{{
public class Foo : Application
{{
public Foo(IntPtr javaReference, {type} transfer) : base(javaReference, transfer)
public Foo({handle} javaReference, {type} transfer) : base(javaReference, transfer)
{{
}}
}}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.Android.Sdk.Analysis/Utilities/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal static string GetNamespaceForParameterType (ParameterSyntax parameterSy
}

// Get the symbol for the type of the parameter
var typeSymbol = semanticModel.GetSymbolInfo (parameterSyntax.Type).Symbol as ITypeSymbol;
var typeSymbol = semanticModel.GetTypeInfo (parameterSyntax.Type).Type;

if (typeSymbol == null) {
return null; // Unable to resolve the symbol
Expand Down

0 comments on commit 9f5dc78

Please sign in to comment.