Skip to content

[TrimmableTypeMap] Add standalone integration coverage for generator-consumed scanner fields#10920

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/add-integration-tests-scanner-fields
Draft

[TrimmableTypeMap] Add standalone integration coverage for generator-consumed scanner fields#10920
Copilot wants to merge 4 commits intomainfrom
copilot/add-integration-tests-scanner-fields

Conversation

Copy link
Contributor

Copilot AI commented Mar 12, 2026

The existing TrimmableTypeMap integration tests only compared fields shared by the legacy Cecil scanner and the new SRM-based scanner. This change adds standalone correctness coverage for scanner fields that are consumed by the generator pipeline but have no legacy equivalent: IsUnconditional, InvokerTypeName, CompatJniName, and MarshalMethodInfo.ManagedMethodName.

  • Add standalone scanner integration tests

    • Add ScannerFieldIntegrationTests under tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/
    • Cover:
      • component-driven and cross-reference-driven IsUnconditional
      • Mono.Android sanity check that MCW bindings are not marked unconditional
      • InvokerTypeName resolution for interfaces and abstract types
      • CompatJniName format for user types
      • non-empty ManagedMethodName for marshal methods, with a known-method spot check
  • Expand the user fixture to exercise missing paths

    • Add fixture types for:
      • [ContentProvider]
      • user-defined interface + invoker
      • abstract Java peer + invoker
    • Keep the fixture focused on generator-consumed scanner concepts rather than legacy/new parity
  • Align CompatJniName generation with compat format

    • Update auto-generated compat JNI names to preserve dots in the namespace portion and only use / before the type name
    • Example:
// Before
UserApp.Models.UserModel -> userapp/models/UserModel

// After
UserApp.Models.UserModel -> userapp.models/UserModel
  • What the new tests assert
    • UserApp.MainActivity, MyBackgroundService, BootReceiver, SettingsProvider => IsUnconditional == true
    • UserApp.MyBackupAgent becomes unconditional via [Application(BackupAgent=typeof(...))]
    • Android.Views.View+IOnClickListener resolves to Android.Views.View+IOnClickListenerInvoker
    • Android.Widget.AbsListView resolves to Android.Widget.AbsListViewInvoker
    • user-defined concrete types keep InvokerTypeName == null
Original prompt

This section details on the original issue you should resolve

<issue_title>[TrimmableTypeMap] Add integration tests for generator-consumed scanner fields</issue_title>
<issue_description># [TrimmableTypeMap] Add integration tests for generator-consumed scanner fields

Part of #10789

Context

PR #10827 added integration tests that validate the new JavaPeerScanner (SRM-based) against the legacy Cecil-based scanner. These tests cover the fields that overlap between the two scanners: JavaName, BaseJavaName, ImplementedInterfaces, MarshalMethods, ActivationCtors, and type flags (IsInterface, IsAbstract, IsGenericDefinition, DoNotGenerateAcw).

However, PR #10808 introduced the Generator pipeline (ModelBuilderTypeMapAssemblyEmitter) which consumes several JavaPeerInfo fields that are new concepts with no legacy equivalent. These fields cannot be validated via legacy-vs-new comparison and need standalone correctness tests.

Fields not covered by integration tests

Field Used by Risk if wrong
IsUnconditional ModelBuilder.IsUnconditionalEntry() — determines 2-arg (unconditional) vs 3-arg (trimmable) TypeMap attribute Wrong trimming behavior — types could be incorrectly trimmed or unnecessarily preserved
InvokerTypeName ModelBuilder.BuildProxyType() — proxy generation for interfaces/abstract types Missing invoker = runtime MissingMethodException when activating interface wrappers
CompatJniName AcwMapWriter — backward-compatible ACW name for acw-map.txt Broken debugging, profiling, or tooling that relies on acw-map.txt
MarshalMethods.ManagedMethodName Future UCO wrapper generation Low risk now, but incorrect values would cause wrong method dispatch

Proposed tests

1. IsUnconditional_ComponentTypes

Scan UserTypesFixture.dll:

  • Types with [Activity], [Service], [BroadcastReceiver], [ContentProvider]IsUnconditional = true
  • Plain Java peer types without component attributes → IsUnconditional = false
  • Types referenced by [Application(BackupAgent=typeof(X))] → forced unconditional via cross-reference

2. IsUnconditional_MonoAndroid

Scan Mono.Android.dll:

  • All MCW binding types have DoNotGenerateAcw=true and should not be marked unconditional
  • Sanity check: count of unconditional types = 0

3. InvokerTypeName_InterfacesAndAbstractTypes

Scan Mono.Android.dll:

  • Every type with IsInterface = true should have a non-null InvokerTypeName
  • The referenced invoker type should actually exist in the scanned assemblies
  • Validate resolution via [Register] connector (primary) and {TypeName}Invoker convention (fallback)

4. InvokerTypeName_UserTypes

Scan UserTypesFixture.dll:

  • Concrete user types → InvokerTypeName = null
  • User-defined interfaces (if present) → invoker resolved correctly

5. CompatJniName_UserTypes

Scan UserTypesFixture.dll:

  • Verify CompatJniName uses lowercased raw namespace format
  • E.g., MyApp.Namespace.MyTypemyapp.namespace/MyType

6. ManagedMethodName_MarshalMethods

Scan Mono.Android.dll:

  • Every MarshalMethodInfo has non-null, non-empty ManagedMethodName
  • Spot-check known types (e.g., Android.App.Activity has OnCreate method)

Notes

  • These tests should live in tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/
  • Unlike the existing comparison tests, these are standalone correctness tests — they validate the new scanner's output against known expectations, not against the legacy scanner
  • The UserTypesFixture may need additional types (e.g., user-defined interfaces, [Application] with BackupAgent) to exercise all paths
    </issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits March 12, 2026 08:34
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copilot AI changed the title [WIP] [TrimmableTypeMap] Add integration tests for generator-consumed scanner fields [TrimmableTypeMap] Add standalone integration coverage for generator-consumed scanner fields Mar 12, 2026
@simonrozsival
Copy link
Member

@copilot build fails:

       "/Users/runner/work/1/s/android/Xamarin.Android.sln" (default target) (1:2) ->
       "/Users/runner/work/1/s/android/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/UserTypesFixture/UserTypesFixture.csproj" (default target) (29:8) ->
       (CoreCompile target) -> 
         /Users/runner/work/1/s/android/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/UserTypesFixture/UserTypes.cs(70,3): error CS7036: There is no argument given that corresponds to the required parameter 'authorities' of 'ContentProviderAttribute.ContentProviderAttribute(string[])' [/Users/runner/work/1/s/android/tests/Microsoft.Android.Sdk.TrimmableTypeMap.IntegrationTests/UserTypesFixture/UserTypesFixture.csproj]

    291 Warning(s)
    1 Error(s)

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 12, 2026

@copilot build fails:

       "/Users/runner/work/1/s/android/Xamarin.Android.sln" (default target) (1:2) ->

...

Fixed in e9900e0. SettingsProvider now passes the required string[] authorities argument to ContentProviderAttribute, and the reported CS7036 error is gone in targeted validation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TrimmableTypeMap] Add integration tests for generator-consumed scanner fields

2 participants