Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,30 @@ public partial class ClassName
}
```

### Missing `IRecord`/Interface Chain (Kotlin `@PublishedApi internal`)
When concrete classes lose an `implements` to a public interface because an
intermediate Kotlin interface is `@PublishedApi internal` (or otherwise has
`visibility=""` from class-parse), the binding generator drops the intermediate
type and strips it from every implementer.

**Do NOT** force `<attr ... name="visibility">public</attr>` on the dropped
interface — `metadata-verify` (build/cake/validations.cake) will fail with
"Preventing exposing/surfacing interfaces with default package accessibility
as public", and it correctly protects against republishing types upstream
explicitly marked internal.

**Instead**, inject the public ancestor directly onto each concrete implementer
using `<add-node>` with an XPath that matches by the dropped intermediate(s):
```xml
<add-node path="/api/package[@name='pkg']/class[implements[@name='pkg.InternalIntermediate']]">
<implements name="pkg.PublicAncestor" name-generic-aware="pkg.PublicAncestor"></implements>
</add-node>
```
This preserves the public chain without exposing the internal intermediary.
See `source/GPS.Metadata.Common.xml` (ReflectedParcelable/Parcelable) and
`source/androidx.health.connect/connect-client/Transforms/Metadata.xml`
(IntervalRecord/InstantaneousRecord/SeriesRecord → Record) for examples.

### Build File Locking Errors (XARLP7024)
Transient parallel build issue. Usually resolves on retry. If persistent, may need to reduce build parallelism in `build/cake/build-and-package.cake`.

Expand Down
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@
"groupId": "androidx.health.connect",
"artifactId": "connect-client",
"version": "1.1.0",
"nugetVersion": "1.1.0.2",
"nugetVersion": "1.1.0.3",
"nugetId": "Xamarin.AndroidX.Health.Connect.ConnectClient"
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@
<attr path="/api/package[@name='androidx.health.connect.client.contracts']/class[@name='ExerciseRouteRequestContract']/method[@name='createIntent' and count(parameter)=2 and parameter[1][@type='android.content.Context'] and parameter[2][@type='java.lang.String']]" name="managedName">CreateIntentImpl</attr>
<attr path="/api/package[@name='androidx.health.connect.client.contracts']/class[@name='ExerciseRouteRequestContract']/method[@name='parseResult' and count(parameter)=2 and parameter[1][@type='int'] and parameter[2][@type='android.content.Intent']]" name="managedName">ParseResultImpl</attr>

<!-- IntervalRecord, InstantaneousRecord, and SeriesRecord are `@PublishedApi internal` in
upstream Kotlin source, so class-parse correctly emits an empty visibility and the
binding generator drops them. That also strips the implements chain on every concrete
record (e.g. SleepSessionRecord -> IntervalRecord -> Record), leaving the records with
no IRecord. Re-attach the public Record interface directly to each concrete record so
Comment thread
jonathanpeppers marked this conversation as resolved.
they remain assignable to IRecord without surfacing the internal intermediaries.
This mirrors the pattern in source/GPS.Metadata.Common.xml for ReflectedParcelable. -->
<add-node path="/api/package[@name='androidx.health.connect.client.records']/class[implements[@name='androidx.health.connect.client.records.IntervalRecord'] or implements[@name='androidx.health.connect.client.records.InstantaneousRecord'] or implements[@name='androidx.health.connect.client.records.SeriesRecord']]">
<implements name="androidx.health.connect.client.records.Record" name-generic-aware="androidx.health.connect.client.records.Record"></implements>
</add-node>

<!-- Fix Units classes IComparable implementation by removing the Comparable interface -->
<remove-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='BloodGlucose']/implements[@name='java.lang.Comparable']" />
<remove-node path="/api/package[@name='androidx.health.connect.client.units']/class[@name='Energy']/implements[@name='java.lang.Comparable']" />
Expand Down