Skip to content

[TrimmableTypeMap] Assembly-level manifest attribute scanning - #11035

Merged
jonathanpeppers merged 8 commits into
mainfrom
dev/simonrozsival/scanner-manifest-attributes
Mar 31, 2026
Merged

jonathanpeppers merged 8 commits into
mainfrom
dev/simonrozsival/scanner-manifest-attributes

Conversation

@simonrozsival

@simonrozsival simonrozsival commented Mar 27, 2026 •

Copy link
Copy Markdown
Member

Summary

Add scanning for assembly-level manifest attributes and wire them into the manifest generator. Replace the shared ManifestModel.cs with individual Scanner record types and a ComponentInfo model for type-level component attributes.

Depends on #10991

Changes

Scanner

  • AssemblyIndex.cs: Add ScanAssemblyAttributes() with shared ParseNameAndProperties() entry point and individual Create*Info static methods for each attribute type. Capture component attribute named properties, intent filters, and metadata on type attributes.
  • JavaPeerScanner.cs: Add ScanAssemblyManifestInfo(), ToComponentInfo(), ParseConnectorDeclaringType(). Wire ComponentAttribute into peer creation.
  • New record files (12): AssemblyManifestInfo, ComponentInfo, IntentFilterInfo, MetaDataInfo, PermissionInfo, PermissionGroupInfo, PermissionTreeInfo, PropertyInfo, UsesConfigurationInfo, UsesFeatureInfo, UsesLibraryInfo, UsesPermissionInfo
  • Delete ManifestModel.cs — replaced by the above records

Generator

  • ManifestGenerator.cs: Remove file-path Generate() overload — IO belongs in the caller. Keep only the XDocument? overload.

Bug fixes

  • ParseUsesFeatureAttribute: Read FixedArguments[0] for the feature name (constructor arg with private setter)
  • UsesLibrary 2-arg ctor: Store FixedArguments[1] (bool) in props so Required=false is not silently lost

Refactoring

  • Hoist ParseNameAndProperties(ca) before the switch in ScanAssemblyAttributes
  • Inline trivial CreatePermissionInfo/CreatePermissionGroupInfo/CreatePermissionTreeInfo
  • Remove unused HasPublicDefaultConstructor property and HasPublicParameterlessCtor method
  • Remove unnecessary XML doc comments on internal record types
  • Remove leading blank lines (leftover from #nullable enable removal)

Tests

  • Add stub attributes to TestFixtures (UsesFeature with private-setter Name, UsesPermission, UsesLibrary with 2-arg ctor, MetaData, IntentFilter)
  • Add [assembly: ...] declarations in TestFixtures/AssemblyAttributes.cs
  • Expose ScanAssemblyManifestInfo() via FixtureTestBase
  • Add AssemblyAttributeScanningTests with 8 scanner tests covering constructor-arg parsing, named-arg-only variants, and the 2-arg ctor

Add scanning for assembly-level attributes ([Application], [Activity],
[Service], [BroadcastReceiver], [ContentProvider], permissions, etc.)
and wire them into the manifest generator via Generate(XDocument?) overload.

Replace ManifestModel.cs with individual Scanner/ record types for
better composability.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 27, 2026 10:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds assembly-level Android manifest attribute scanning to the TrimmableTypeMap scanner pipeline and wires the collected data into manifest generation (plus adjusts native callback naming expectations in tests).

Changes:

  • Introduce new scanner model record types to represent assembly-level manifest concepts (permissions, uses-* entries, app-level metadata/properties).
  • Extend AssemblyIndex/JavaPeerScanner to parse and aggregate assembly-level manifest attributes and attach component attribute info to peers.
  • Refactor ManifestGenerator to support an optional pre-loaded XDocument template and update tests for the refined native callback naming.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Scanner/OverrideDetectionTests.cs Updates expected native callback name derived from connector signature.
tests/Microsoft.Android.Sdk.TrimmableTypeMap.Tests/Generator/JcwJavaSourceGeneratorTests.cs Updates expected generated Java to call/declare the refined native callback name.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/UsesPermissionInfo.cs New record for data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/UsesLibraryInfo.cs New record for data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/UsesFeatureInfo.cs New record for data (name vs GL ES variant).
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/UsesConfigurationInfo.cs New record for data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PropertyInfo.cs New record for entries under .
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PermissionTreeInfo.cs New record for data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PermissionInfo.cs New record for data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PermissionGroupInfo.cs New record for data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/MetaDataInfo.cs New record for items.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/IntentFilterInfo.cs New record for intent filter data captured from [IntentFilter].
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/ComponentInfo.cs New public model for component attribute data used by manifest generation.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyManifestInfo.cs New aggregate container for assembly-level manifest attributes across scanned assemblies.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyIndex.cs Adds ScanAssemblyAttributes() and parsing for assembly-level attributes; expands type-attribute parsing to capture properties/intent-filters/metadata.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerScanner.cs Adds assembly-manifest scanning entry point, component mapping, and improved native callback name derivation from connector strings.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs Updates doc comment for ComponentAttribute.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ManifestModel.cs Deletes legacy shared manifest model (replaced by scanner record types).
src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/ManifestGenerator.cs Adds Generate(XDocument?, ...) overload and refactors template loading/default manifest creation.

Comment thread src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/AssemblyIndex.cs Outdated
… types

Add assembly-level manifest attribute scanning to the TrimmableTypeMap scanner:

- AssemblyIndex.ScanAssemblyAttributes(): parses 9 assembly-level attribute types
  (UsesPermission, UsesLibrary, UsesFeature, UsesConfiguration, Permission,
  PermissionGroup, PermissionTree, MetaData, Property)
- JavaPeerScanner.ScanAssemblyManifestInfo(): aggregates attributes across assemblies
- JavaPeerScanner.ToComponentInfo()/HasPublicParameterlessCtor(): attaches component
  info to scanned peers
- ManifestGenerator.Generate(XDocument?): new overload accepting pre-loaded template
- ManifestGenerator.CreateDefaultManifest(): extracted from LoadOrCreateManifest
- Replace ManifestModel.cs (105-line flat class) with 12 focused record types
- Update JavaPeerInfo.ComponentAttribute doc comment

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
simonrozsival and others added 5 commits March 27, 2026 13:06
…e enable

- Fix ParseAttributes: collect IntentFilter/MetaData in local lists and attach
  after the loop to avoid creating attrInfo with wrong AttributeName when
  [IntentFilter] appears before [Activity]
- Remove redundant #nullable enable from 13 files (project has enable)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…e name

UsesFeatureAttribute.Name has a private setter and is set via the
(string name) constructor. The parser only read NamedArguments, so
the feature name was always null when set via the constructor,
causing  entries to be silently skipped.

Read FixedArguments[0] first (matching ParseUsesPermissionAttribute
and ParseUsesLibraryAttribute), then allow NamedArguments to override.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add stub attributes (UsesFeatureAttribute with private-setter Name,
UsesPermissionAttribute, UsesLibraryAttribute, MetaDataAttribute,
IntentFilterAttribute) and assembly-level usages in TestFixtures.

Expose ScanAssemblyManifestInfo() via FixtureTestBase and add 6 tests
in AssemblyAttributeScanningTests covering constructor-arg parsing for
UsesFeature, UsesPermission, UsesLibrary, MetaData, and the GLESVersion
named-arg-only variant.

The UsesFeature_ConstructorArg and UsesFeature_ConstructorArgWithNamedProperty
tests are regression tests for the ParseUsesFeatureAttribute fix.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove leading blank lines from 13 files (leftover from #nullable enable removal)
- Remove unnecessary XML doc comments on internal record types
- Remove unused HasPublicDefaultConstructor property and HasPublicParameterlessCtor method
- Enhance ParseNameAndProperties to also read FixedArguments[0] for constructor-arg names
- Refactor individual Parse*Attribute methods into static Create*Info methods that
  accept pre-parsed (name, props) from ParseNameAndProperties, eliminating duplicated
  DecodeAttribute calls and NamedArguments iteration

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…overload

- Move ParseNameAndProperties(ca) call before the switch in ScanAssemblyAttributes
  so it runs once instead of being duplicated in every case
- Inline trivial CreatePermissionInfo/CreatePermissionGroupInfo/CreatePermissionTreeInfo
  one-liners directly at the call site
- Remove the file-path Generate() overload from ManifestGenerator; IO belongs in the caller
- Fix leading blank line in ManifestGeneratorTests.cs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@simonrozsival
simonrozsival force-pushed the dev/simonrozsival/scanner-manifest-attributes branch from 1239c1b to e93ba6b Compare March 30, 2026 11:57
UsesLibraryAttribute(string, bool) puts Required in FixedArguments[1].
ParseNameAndProperties now stores additional bool ctor args in props
so CreateUsesLibraryInfo can read them.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@simonrozsival simonrozsival left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

🤖 AI Review Summary

Verdict: ✅ LGTM

Found 0 errors, 0 warnings, 1 suggestion.

CI: dotnet-android all 3 legs green (Linux ✅, Mac ✅, Windows ✅). Xamarin.Android-PR pending (rerun queued).

👍 Positive callouts

  • Clean shared ParseNameAndProperties entry point with KnownAssemblyAttributes guard — avoids decoding non-manifest attributes
  • FixedArguments[0] read for constructor-arg names (UsesFeature, UsesPermission, UsesLibrary, MetaData, SupportsGLTexture, Property)
  • FixedArguments[1] read for UsesLibrary 2-arg ctor (string, bool) — prevents silent Required loss
  • HashSet.Add() pattern for all dedup sets — prevents cross-assembly duplicates
  • 8 scanner tests covering constructor-arg parsing, named-arg-only variants, and 2-arg ctor regression
  • Visibility split is correct: ComponentInfo/IntentFilterInfo/MetaDataInfo public (exposed via JavaPeerInfo), all others internal
  • No null!, no #region, no string.Empty, no Array.Empty(), no leading blank lines

💡 Documentation — PR description is out of date (still mentions removed HasPublicParameterlessCtor/GetNativeCallbackName, doesn't mention bug fixes or tests). Consider updating it before review.


Review generated by android-reviewer from review guidelines.

@jonathanpeppers jonathanpeppers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall looks good. I'm rerunning some of the lanes that failed.

@jonathanpeppers
jonathanpeppers merged commit 4f265cc into main Mar 31, 2026
5 of 6 checks passed
@jonathanpeppers
jonathanpeppers deleted the dev/simonrozsival/scanner-manifest-attributes branch March 31, 2026 14:50
@github-actions github-actions Bot locked and limited conversation to collaborators May 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

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.

3 participants