Skip to content

Commit 01136d4

Browse files
committed
Simplify: remove premature ComponentDataSerializer and TrimmableTypeMapGenerator
Remove 1,280 lines of unnecessary code: - ComponentDataSerializer (349 lines) + tests (512 lines): custom text serializer with no consumer — ScannerManifestTypeInfoAdapter already converts JavaPeerInfo → IManifestTypeInfo directly - TrimmableTypeMapGenerator (118 lines) + tests (212 lines): pipeline orchestrator with no caller — individual pieces are independently tested Also trim verbose doc comments and simplify null-coalescing in ScannerManifestTypeInfoAdapter. All 318 tests pass.
1 parent ea4faeb commit 01136d4

File tree

10 files changed

+40
-1320
lines changed

10 files changed

+40
-1320
lines changed

src/Microsoft.Android.Sdk.TrimmableTypeMap/AcwMapWriter.cs

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,20 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5-
using System.Text;
65

76
namespace Microsoft.Android.Sdk.TrimmableTypeMap;
87

98
/// <summary>
109
/// Generates acw-map.txt from JavaPeerInfo scanner results.
11-
/// The acw-map format is consumed by _ConvertCustomView to fix up
12-
/// custom view names in layout XML files.
13-
///
14-
/// Each type produces up to 3 lines:
15-
/// PartialAssemblyQualifiedName;JavaKey
16-
/// ManagedKey;JavaKey
17-
/// CompatJniName;JavaKey
10+
/// The acw-map is consumed by _ConvertCustomView to fix up custom view names in layout XML.
1811
///
12+
/// Each type produces 3 lines: PartialAssemblyQualifiedName;JavaKey, ManagedKey;JavaKey, CompatJniName;JavaKey.
1913
/// Types with DoNotGenerateAcw = true are excluded (MCW binding types).
2014
/// </summary>
2115
static class AcwMapWriter
2216
{
2317
/// <summary>
24-
/// Writes per-assembly acw-map lines for a single assembly's scan results.
25-
/// Returns the lines (not yet written to disk) so they can be merged later.
18+
/// Creates per-assembly acw-map entries for a single assembly's scan results.
2619
/// </summary>
2720
public static List<AcwMapEntry> CreateEntries (IReadOnlyList<JavaPeerInfo> peers, string assemblyName)
2821
{
@@ -54,9 +47,7 @@ public static List<AcwMapEntry> CreateEntries (IReadOnlyList<JavaPeerInfo> peers
5447
}
5548

5649
/// <summary>
57-
/// Writes acw-map.txt from merged entries.
58-
/// Detects XA4214 (duplicate managed key) and XA4215 (duplicate Java key) conflicts.
59-
/// Returns true if no errors were found, false if XA4215 errors prevent output.
50+
/// Writes acw-map.txt, detecting XA4214 (duplicate managed key) and XA4215 (duplicate Java key).
6051
/// </summary>
6152
public static AcwMapResult WriteMap (IReadOnlyList<AcwMapEntry> entries, TextWriter writer)
6253
{
@@ -111,8 +102,7 @@ public static AcwMapResult WriteMap (IReadOnlyList<AcwMapEntry> entries, TextWri
111102
}
112103

113104
/// <summary>
114-
/// Convenience: writes acw-map.txt to a file, only if content changed.
115-
/// Returns the result with conflict information.
105+
/// Writes acw-map.txt to a file, only if content changed.
116106
/// </summary>
117107
public static AcwMapResult WriteMapToFile (IReadOnlyList<AcwMapEntry> entries, string outputPath)
118108
{

src/Microsoft.Android.Sdk.TrimmableTypeMap/Manifest/IManifestTypeInfo.cs

Lines changed: 8 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ namespace Microsoft.Android.Sdk.TrimmableTypeMap;
44

55
/// <summary>
66
/// Component kind for manifest generation.
7-
/// Determines which XML element is generated in the merged AndroidManifest.xml.
87
/// </summary>
98
enum ManifestComponentKind
109
{
@@ -19,7 +18,6 @@ enum ManifestComponentKind
1918

2019
/// <summary>
2120
/// Holds raw attribute property data extracted from either Cecil or SRM.
22-
/// The consumer (ManifestDocument) creates strongly-typed attribute objects from this data.
2321
/// </summary>
2422
sealed class ComponentAttributeInfo
2523
{
@@ -29,97 +27,46 @@ sealed class ComponentAttributeInfo
2927
public string AttributeType { get; set; } = "";
3028

3129
/// <summary>
32-
/// Named property values from the attribute, e.g., { "MainLauncher": true, "Label": "My App" }.
33-
/// Values are already decoded to their .NET types (string, bool, int, Type name as string, enum as int).
30+
/// Named property values, e.g., { "MainLauncher": true, "Label": "My App" }.
31+
/// Values are decoded .NET types (string, bool, int, Type name as string, enum as int).
3432
/// </summary>
3533
public IReadOnlyDictionary<string, object> Properties { get; set; } = new Dictionary<string, object> ();
3634

3735
/// <summary>
38-
/// Constructor arguments (positional), e.g., for ContentProviderAttribute(string[] authorities).
39-
/// Values are already decoded.
36+
/// Constructor arguments (positional), e.g., ContentProviderAttribute(string[] authorities).
4037
/// </summary>
4138
public IReadOnlyList<object> ConstructorArguments { get; set; } = [];
4239
}
4340

4441
/// <summary>
4542
/// Abstraction over a Java peer type for manifest generation.
4643
/// Implemented by both Cecil (legacy) and SRM (trimmable) adapters.
47-
/// This interface contains all data ManifestDocument.Merge() needs,
48-
/// without any dependency on Cecil or SRM.
44+
/// Contains all data ManifestDocument.Merge() needs without Cecil/SRM dependency.
4945
/// </summary>
5046
interface IManifestTypeInfo
5147
{
52-
/// <summary>
53-
/// Full managed type name, e.g., "MyApp.MainActivity".
54-
/// </summary>
5548
string FullName { get; }
56-
57-
/// <summary>
58-
/// Managed type namespace, e.g., "MyApp".
59-
/// </summary>
6049
string Namespace { get; }
6150

62-
/// <summary>
63-
/// Java type name in dotted format for manifest, e.g., "my.app.MainActivity".
64-
/// Derived from JNI name by replacing '/' with '.'.
65-
/// </summary>
51+
/// <summary>Java type name in dotted format, e.g., "my.app.MainActivity".</summary>
6652
string JavaName { get; }
6753

68-
/// <summary>
69-
/// Compatibility Java name (e.g., with md5 hash for auto-generated names).
70-
/// Used for backward-compatible manifest entries.
71-
/// </summary>
54+
/// <summary>Compat Java name (e.g., with md5 hash for auto-generated names).</summary>
7255
string CompatJavaName { get; }
7356

74-
/// <summary>
75-
/// Whether this is an abstract type. Abstract types are skipped during manifest generation.
76-
/// </summary>
7757
bool IsAbstract { get; }
7858

79-
/// <summary>
80-
/// Whether this type has a public parameterless constructor.
81-
/// Required for component types (Activity, Service, etc.) — XA4213 if missing.
82-
/// </summary>
59+
/// <summary>Required for component types — XA4213 if missing.</summary>
8360
bool HasPublicParameterlessConstructor { get; }
8461

85-
/// <summary>
86-
/// The kind of Android manifest component this type represents.
87-
/// Determined by base class: Activity, Service, BroadcastReceiver, ContentProvider,
88-
/// Application, Instrumentation, or None for non-component types.
89-
/// </summary>
9062
ManifestComponentKind ComponentKind { get; }
9163

92-
/// <summary>
93-
/// Raw property data for the primary component attribute (e.g., [Activity], [Service]).
94-
/// Null if ComponentKind is None.
95-
/// </summary>
64+
/// <summary>Raw data for the primary component attribute. Null if ComponentKind is None.</summary>
9665
ComponentAttributeInfo? ComponentAttribute { get; }
9766

98-
/// <summary>
99-
/// Intent filter attributes applied to this type.
100-
/// Each entry contains the raw property data for one [IntentFilter] attribute.
101-
/// </summary>
10267
IReadOnlyList<ComponentAttributeInfo> IntentFilters { get; }
103-
104-
/// <summary>
105-
/// Metadata attributes applied to this type.
106-
/// Each entry contains the raw property data for one [MetaData] attribute.
107-
/// </summary>
10868
IReadOnlyList<ComponentAttributeInfo> MetaDataEntries { get; }
109-
110-
/// <summary>
111-
/// Property attributes applied to this type.
112-
/// Each entry contains the raw property data for one [Property] attribute.
113-
/// </summary>
11469
IReadOnlyList<ComponentAttributeInfo> PropertyAttributes { get; }
115-
116-
/// <summary>
117-
/// Layout attribute data, if present. Used only for Activity types.
118-
/// </summary>
11970
ComponentAttributeInfo? LayoutAttribute { get; }
120-
121-
/// <summary>
122-
/// Grant URI permission attributes. Used only for ContentProvider types.
123-
/// </summary>
12471
IReadOnlyList<ComponentAttributeInfo> GrantUriPermissions { get; }
12572
}
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
using System;
21
using System.Collections.Generic;
32

43
namespace Microsoft.Android.Sdk.TrimmableTypeMap;
54

65
/// <summary>
76
/// Default mutable implementation of <see cref="IManifestTypeInfo"/>.
8-
/// Used by both Cecil and SRM adapters to populate manifest type data.
97
/// </summary>
108
sealed class ManifestTypeInfo : IManifestTypeInfo
119
{
@@ -17,9 +15,9 @@ sealed class ManifestTypeInfo : IManifestTypeInfo
1715
public bool HasPublicParameterlessConstructor { get; set; }
1816
public ManifestComponentKind ComponentKind { get; set; }
1917
public ComponentAttributeInfo? ComponentAttribute { get; set; }
20-
public IReadOnlyList<ComponentAttributeInfo> IntentFilters { get; set; } = Array.Empty<ComponentAttributeInfo> ();
21-
public IReadOnlyList<ComponentAttributeInfo> MetaDataEntries { get; set; } = Array.Empty<ComponentAttributeInfo> ();
22-
public IReadOnlyList<ComponentAttributeInfo> PropertyAttributes { get; set; } = Array.Empty<ComponentAttributeInfo> ();
18+
public IReadOnlyList<ComponentAttributeInfo> IntentFilters { get; set; } = [];
19+
public IReadOnlyList<ComponentAttributeInfo> MetaDataEntries { get; set; } = [];
20+
public IReadOnlyList<ComponentAttributeInfo> PropertyAttributes { get; set; } = [];
2321
public ComponentAttributeInfo? LayoutAttribute { get; set; }
24-
public IReadOnlyList<ComponentAttributeInfo> GrantUriPermissions { get; set; } = Array.Empty<ComponentAttributeInfo> ();
22+
public IReadOnlyList<ComponentAttributeInfo> GrantUriPermissions { get; set; } = [];
2523
}
Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
using System;
21
using System.Collections.Generic;
32

43
namespace Microsoft.Android.Sdk.TrimmableTypeMap;
54

65
/// <summary>
7-
/// Converts JavaPeerInfo + ComponentData (from the SRM-based scanner) into
8-
/// IManifestTypeInfo for consumption by ManifestDocument.Merge().
9-
/// This adapter runs in the trimmable path — no Cecil dependency.
6+
/// Converts JavaPeerInfo (from the SRM-based scanner) into IManifestTypeInfo
7+
/// for consumption by ManifestDocument.Merge(). No Cecil dependency.
108
/// </summary>
119
static class ScannerManifestTypeInfoAdapter
1210
{
13-
/// <summary>
14-
/// Creates IManifestTypeInfo objects from scan results.
15-
/// ComponentData is now carried by JavaPeerInfo itself (populated during scanning).
16-
/// </summary>
11+
static readonly IReadOnlyList<ComponentAttributeInfo> EmptyAttributes = new ComponentAttributeInfo [0];
12+
1713
public static List<IManifestTypeInfo> Convert (IReadOnlyList<JavaPeerInfo> peers)
1814
{
1915
var result = new List<IManifestTypeInfo> (peers.Count);
@@ -22,51 +18,41 @@ public static List<IManifestTypeInfo> Convert (IReadOnlyList<JavaPeerInfo> peers
2218
if (peer.DoNotGenerateAcw)
2319
continue;
2420

25-
var componentData = peer.ComponentData;
26-
21+
var cd = peer.ComponentData;
2722
var javaName = peer.JavaName.Replace ('/', '.');
28-
var info = new ManifestTypeInfo {
23+
24+
result.Add (new ManifestTypeInfo {
2925
FullName = peer.ManagedTypeName,
3026
Namespace = peer.ManagedTypeNamespace,
3127
JavaName = javaName,
32-
CompatJavaName = javaName, // TODO: compute compat name with md5 hash when needed
28+
CompatJavaName = javaName,
3329
IsAbstract = peer.IsAbstract,
3430
HasPublicParameterlessConstructor = HasPublicDefaultCtor (peer),
35-
ComponentKind = componentData?.ComponentKind ?? ManifestComponentKind.None,
36-
ComponentAttribute = componentData?.ComponentAttribute,
37-
IntentFilters = componentData?.IntentFilters ?? (IReadOnlyList<ComponentAttributeInfo>)Array.Empty<ComponentAttributeInfo> (),
38-
MetaDataEntries = componentData?.MetaDataEntries ?? (IReadOnlyList<ComponentAttributeInfo>)Array.Empty<ComponentAttributeInfo> (),
39-
PropertyAttributes = componentData?.PropertyAttributes ?? (IReadOnlyList<ComponentAttributeInfo>)Array.Empty<ComponentAttributeInfo> (),
40-
LayoutAttribute = componentData?.LayoutAttribute,
41-
GrantUriPermissions = componentData?.GrantUriPermissions ?? (IReadOnlyList<ComponentAttributeInfo>)Array.Empty<ComponentAttributeInfo> (),
42-
};
43-
44-
result.Add (info);
31+
ComponentKind = cd?.ComponentKind ?? ManifestComponentKind.None,
32+
ComponentAttribute = cd?.ComponentAttribute,
33+
IntentFilters = cd?.IntentFilters ?? EmptyAttributes,
34+
MetaDataEntries = cd?.MetaDataEntries ?? EmptyAttributes,
35+
PropertyAttributes = cd?.PropertyAttributes ?? EmptyAttributes,
36+
LayoutAttribute = cd?.LayoutAttribute,
37+
GrantUriPermissions = cd?.GrantUriPermissions ?? EmptyAttributes,
38+
});
4539
}
4640

4741
return result;
4842
}
4943

50-
/// <summary>
51-
/// Scans a set of assemblies and produces IManifestTypeInfo objects.
52-
/// </summary>
5344
public static List<IManifestTypeInfo> ScanAndConvert (IReadOnlyList<string> assemblyPaths)
5445
{
5546
using var scanner = new JavaPeerScanner ();
56-
var peers = scanner.Scan (assemblyPaths);
57-
return Convert (peers);
47+
return Convert (scanner.Scan (assemblyPaths));
5848
}
5949

6050
static bool HasPublicDefaultCtor (JavaPeerInfo peer)
6151
{
62-
// If there are any registered constructors, check for a parameterless one
6352
foreach (var ctor in peer.JavaConstructors) {
6453
if (ctor.JniSignature == "()V")
6554
return true;
6655
}
67-
68-
// Types with activation ctors have some constructor available
69-
// but the check for XA4213 is about a public parameterless ctor
7056
return false;
7157
}
7258
}

src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/ComponentAttributeExtractor.cs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
namespace Microsoft.Android.Sdk.TrimmableTypeMap;
66

77
/// <summary>
8-
/// Extracts component attribute data (Activity, Service, BroadcastReceiver, ContentProvider,
9-
/// Application, Instrumentation) and sub-attribute data (IntentFilter, MetaData, Property,
10-
/// Layout, GrantUriPermission) from SRM CustomAttribute blobs.
11-
///
12-
/// All attribute properties are decoded into <see cref="ComponentAttributeInfo"/> objects
13-
/// containing raw name-value dictionaries — no Cecil dependency.
8+
/// Extracts component attribute data ([Activity], [Service], etc.) and sub-attributes
9+
/// ([IntentFilter], [MetaData], [Layout], [Property], [GrantUriPermission])
10+
/// from SRM CustomAttribute blobs into <see cref="ComponentData"/>.
1411
/// </summary>
1512
static class ComponentAttributeExtractor
1613
{
@@ -33,7 +30,7 @@ static class ComponentAttributeExtractor
3330
};
3431

3532
/// <summary>
36-
/// Extracts all component and sub-attribute data from the custom attributes of a type.
33+
/// Extracts all component and sub-attribute data from a type's custom attributes.
3734
/// </summary>
3835
public static ComponentData Extract (MetadataReader reader, TypeDefinitionHandle typeHandle)
3936
{
@@ -75,10 +72,6 @@ public static ComponentData Extract (MetadataReader reader, TypeDefinitionHandle
7572
return result;
7673
}
7774

78-
/// <summary>
79-
/// Decodes a CustomAttribute blob into a ComponentAttributeInfo.
80-
/// Extracts both constructor arguments and named properties.
81-
/// </summary>
8275
static ComponentAttributeInfo DecodeAttribute (MetadataReader reader, CustomAttribute ca, CustomAttributeTypeProvider provider, string attrName)
8376
{
8477
var decoded = ca.DecodeValue (provider);
@@ -104,8 +97,7 @@ static ComponentAttributeInfo DecodeAttribute (MetadataReader reader, CustomAttr
10497
}
10598

10699
/// <summary>
107-
/// Normalizes decoded attribute values to consistent types.
108-
/// SRM may return boxed primitives, ImmutableArray, or strings.
100+
/// Normalizes SRM decoded values (boxed primitives, ImmutableArray) to consistent types.
109101
/// </summary>
110102
static object NormalizeValue (object? value)
111103
{

src/Microsoft.Android.Sdk.TrimmableTypeMap/Scanner/JavaPeerInfo.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@ sealed class JavaPeerInfo
9696
public bool IsGenericDefinition { get; set; }
9797

9898
/// <summary>
99-
/// Component attribute data extracted from the type (Activity, Service, etc.).
100-
/// Null if the type has no component attributes.
101-
/// Used by manifest generation and the ScannerManifestTypeInfoAdapter.
99+
/// Component attribute data ([Activity], [Service], etc.). Null if no component attributes.
102100
/// </summary>
103101
public ComponentData? ComponentData { get; set; }
104102
}

0 commit comments

Comments
 (0)