@@ -40,7 +40,7 @@ public TrimmableTypeMapResult Execute (
4040 return new TrimmableTypeMapResult ( [ ] , [ ] , allPeers ) ;
4141 }
4242
43- RootManifestReferencedTypes ( allPeers , manifestTemplatePath ) ;
43+ RootManifestReferencedTypes ( allPeers , manifestTemplate ) ;
4444
4545 var generatedAssemblies = GenerateTypeMapAssemblies ( allPeers , systemRuntimeVersion ) ;
4646 var jcwPeers = allPeers . Where ( p =>
@@ -144,32 +144,15 @@ List<GeneratedJavaSource> GenerateJcwJavaSources (List<JavaPeerInfo> allPeers)
144144 return sources . ToList ( ) ;
145145 }
146146
147- void RootManifestReferencedTypes ( List < JavaPeerInfo > allPeers , string ? manifestTemplatePath )
147+ internal void RootManifestReferencedTypes ( List < JavaPeerInfo > allPeers , XDocument ? doc )
148148 {
149- if ( manifestTemplatePath . IsNullOrEmpty ( ) || ! File . Exists ( manifestTemplatePath ) ) {
150- return ;
151- }
152-
153- XDocument doc ;
154- try {
155- doc = XDocument . Load ( manifestTemplatePath ) ;
156- } catch ( Exception ex ) {
157- warn ? . Invoke ( $ "Failed to parse ManifestTemplate '{ manifestTemplatePath } ': { ex . Message } ") ;
158- return ;
159- }
160-
161- RootManifestReferencedTypes ( allPeers , doc ) ;
162- }
163-
164- internal void RootManifestReferencedTypes ( List < JavaPeerInfo > allPeers , XDocument doc )
165- {
166- var root = doc . Root ;
167- if ( root is null ) {
149+ if ( doc ? . Root is not { } root ) {
168150 return ;
169151 }
170152
171153 XNamespace androidNs = "http://schemas.android.com/apk/res/android" ;
172154 XName attName = androidNs + "name" ;
155+ var packageName = ( string ? ) root . Attribute ( "package" ) ?? "" ;
173156
174157 var componentNames = new HashSet < string > ( StringComparer . Ordinal ) ;
175158 foreach ( var element in root . Descendants ( ) ) {
@@ -180,7 +163,7 @@ internal void RootManifestReferencedTypes (List<JavaPeerInfo> allPeers, XDocumen
180163 case "provider" :
181164 var name = ( string ? ) element . Attribute ( attName ) ;
182165 if ( name is not null ) {
183- componentNames . Add ( name ) ;
166+ componentNames . Add ( ResolveManifestClassName ( name , packageName ) ) ;
184167 }
185168 break ;
186169 }
@@ -190,9 +173,10 @@ internal void RootManifestReferencedTypes (List<JavaPeerInfo> allPeers, XDocumen
190173 return ;
191174 }
192175
176+ // Build lookup by dot-name, keeping '$' for nested types (manifests use '$' too).
193177 var peersByDotName = new Dictionary < string , List < JavaPeerInfo > > ( StringComparer . Ordinal ) ;
194178 foreach ( var peer in allPeers ) {
195- var dotName = peer . JavaName . Replace ( '/' , '.' ) . Replace ( '$' , '.' ) ;
179+ var dotName = peer . JavaName . Replace ( '/' , '.' ) ;
196180 if ( ! peersByDotName . TryGetValue ( dotName , out var list ) ) {
197181 list = [ ] ;
198182 peersByDotName [ dotName ] = list ;
@@ -213,4 +197,22 @@ internal void RootManifestReferencedTypes (List<JavaPeerInfo> allPeers, XDocumen
213197 }
214198 }
215199 }
200+
201+ /// <summary>
202+ /// Resolves an android:name value to a fully-qualified class name.
203+ /// Names starting with '.' are relative to the package. Names with no '.' at all
204+ /// are also treated as relative (Android tooling convention).
205+ /// </summary>
206+ static string ResolveManifestClassName ( string name , string packageName )
207+ {
208+ if ( name . StartsWith ( "." , StringComparison . Ordinal ) ) {
209+ return packageName + name ;
210+ }
211+
212+ if ( name . IndexOf ( '.' ) < 0 && ! packageName . IsNullOrEmpty ( ) ) {
213+ return packageName + "." + name ;
214+ }
215+
216+ return name ;
217+ }
216218}
0 commit comments