Skip to content

[TrimmableTypeMap] Assembly-level manifest attribute scanning#11035

Open
simonrozsival wants to merge 8 commits intomainfrom
dev/simonrozsival/scanner-manifest-attributes
Open

[TrimmableTypeMap] Assembly-level manifest attribute scanning#11035
simonrozsival wants to merge 8 commits intomainfrom
dev/simonrozsival/scanner-manifest-attributes

Conversation

@simonrozsival
Copy link
Copy Markdown
Member

@simonrozsival simonrozsival commented Mar 27, 2026

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
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

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 <uses-permission> data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/UsesLibraryInfo.cs New record for <uses-library> data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/UsesFeatureInfo.cs New record for <uses-feature> data (name vs GL ES variant).
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/UsesConfigurationInfo.cs New record for <uses-configuration> data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PropertyInfo.cs New record for <property> entries under <application>.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PermissionTreeInfo.cs New record for <permission-tree> data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PermissionInfo.cs New record for <permission> data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/PermissionGroupInfo.cs New record for <permission-group> data.
src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/MetaDataInfo.cs New record for <meta-data> 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.

… 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 <Nullable>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 <uses-feature> 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>
Copy link
Copy Markdown
Member Author

@simonrozsival simonrozsival left a comment

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<T>(), 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.

Copy link
Copy Markdown
Member

@jonathanpeppers jonathanpeppers left a comment

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.

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.

3 participants