Skip to content

[TrimmableTypeMap] Fix constructor UCO generation#11296

Open
Copilot wants to merge 7 commits into
mainfrom
copilot/fix-generated-constructor-uco-methods
Open

[TrimmableTypeMap] Fix constructor UCO generation#11296
Copilot wants to merge 7 commits into
mainfrom
copilot/fix-generated-constructor-uco-methods

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 6, 2026

Generated trimmable typemap constructor UCO wrappers were activating peers through the (IntPtr, JniHandleOwnership) constructor even when Java invoked a managed constructor with parameters. This skipped JNI argument resolution and called the wrong constructor.

  • Constructor metadata flow

    • Carry concrete managed constructor parameter types from scanner results into the typemap model.
    • Preserve the declaring type/assembly for constructor calls emitted into the typemap assembly.
  • UCO IL generation

    • Emit direct calls to the matching managed constructor when available.
    • Convert JNI object parameters with JavaConvert.FromJniHandle<T>().
    • Set the peer reference before invoking the managed constructor.
    • Keep activation-only fallback behavior for inherited seed constructors with no concrete managed constructor.
  • Regression coverage

    • Add generator tests that inspect emitted IL for:
      • nctor_*_uco calling the matching managed constructor.
      • JNI object handle conversion before constructor invocation.

Example generated behavior now follows the Java constructor signature:

// Java invokes: nctor_1(self, contextHandle)
// Generated UCO now resolves contextHandle and calls:
obj.SetPeerReference(new JniObjectReference(self));
obj.CustomView(JavaConvert.FromJniHandle<Context>(
    contextHandle,
    JniHandleOwnership.DoNotTransfer));

Copilot AI and others added 2 commits May 6, 2026 09:47
Agent-Logs-Url: https://github.com/dotnet/android/sessions/2a0c90c9-484f-417c-875c-bea6afda1c98

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/android/sessions/2a0c90c9-484f-417c-875c-bea6afda1c98

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix generated constructor UCO methods in TrimmableTypeMap Fix trimmable typemap constructor UCO generation May 6, 2026
Copilot AI requested a review from simonrozsival May 6, 2026 09:52
@simonrozsival simonrozsival changed the title Fix trimmable typemap constructor UCO generation [TrimmableTypeMap] Fix constructor UCO generation May 7, 2026
@simonrozsival simonrozsival added copilot `copilot-cli` or other AIs were used to author this trimmable-type-map labels May 7, 2026
@simonrozsival simonrozsival marked this pull request as ready for review May 11, 2026 08:18
Copilot AI review requested due to automatic review settings May 11, 2026 08:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes trimmable typemap-generated UCO constructor wrappers so they invoke the correct managed constructor when Java calls a constructor with parameters (instead of always activating via the (IntPtr, JniHandleOwnership) activation constructor). This aligns constructor behavior with the Java signature and ensures JNI arguments are properly resolved (including object-handle conversion).

Changes:

  • Extend scanner/model to carry concrete managed constructor parameter types (and declaring type/assembly) into the typemap model.
  • Update typemap IL emission to support direct managed constructor invocation, converting JNI object handles via JavaConvert.FromJniHandle<T>() and setting peer references before the call.
  • Add generator tests that inspect emitted IL to verify direct constructor calls and JNI handle conversion.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/TypeMapAssemblyGeneratorTests.cs Adds IL-inspection regression tests for UCO constructor direct-call behavior and handle conversion.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs Captures managed constructor parameter type info (and resolves parameter type assemblies) for constructors during scanning.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs Extends scanner data model with managed constructor parameter metadata and introduces ManagedParameterInfo.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs Emits direct managed-constructor activation IL path and supports encoding managed parameter types + JavaConvert.FromJniHandle<T>() calls.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ModelBuilder.cs Plumbs constructor parameter metadata into UcoConstructorData for emitter consumption.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/Model/TypeMapAssemblyData.cs Extends UcoConstructorData with managed constructor parameter metadata and declaring type info.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/MetadataHelper.cs Updates typemap content fingerprint to include UCO constructor managed-parameter metadata (but needs a null vs empty fix).

Comment on lines +51 to +52
writer.Write (0);
} else {
Comment on lines 892 to 901
bool isConstructor = registerInfo.JniName == "<init>" || registerInfo.JniName == ".ctor";
bool isExport = exportInfo is not null;
string managedName = index.Reader.GetString (methodDef.Name);
string jniSignature = registerInfo.Signature ?? "()V";

string declaringTypeName = "";
string declaringAssemblyName = "";
ParseConnectorDeclaringType (registerInfo.Connector, out declaringTypeName, out declaringAssemblyName);
var sig = methodDef.DecodeSignature (SignatureTypeProvider.Instance, genericContext: default);

@simonrozsival
Copy link
Copy Markdown
Member

@copilot address review comments

Copilot AI and others added 2 commits May 11, 2026 08:53
Agent-Logs-Url: https://github.com/dotnet/android/sessions/b8ec3a3d-baa2-4abe-8db9-4a2aa9cfb59c

Co-authored-by: simonrozsival <374616+simonrozsival@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/android/sessions/b8ec3a3d-baa2-4abe-8db9-4a2aa9cfb59c

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

Copilot AI commented May 11, 2026

@copilot address review comments

Addressed the review comments in 279baeb: the fingerprint now distinguishes null vs empty constructor parameter metadata, and non-constructor marshal methods no longer decode managed signatures. I also pushed a small test-name cleanup in 56db38f.

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

Labels

copilot `copilot-cli` or other AIs were used to author this trimmable-type-map

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[TrimmableTypeMap] Fix generated constructor UCO methods

3 participants