Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
59e8c7e
[TrimmableTypeMap] Prototype: emit per-assembly typemaps without the …
simonrozsival Jul 15, 2026
24be1cd
[TrimmableTypeMap] Root: reference pre-generated framework typemaps u…
simonrozsival Jul 15, 2026
4038237
[TrimmableTypeMap] Pre-generate Mono.Android typemap at SDK build time
simonrozsival Jul 15, 2026
0204e15
[TrimmableTypeMap] Emit pre-built Mono.Android typemap into the SDK p…
simonrozsival Jul 15, 2026
2ecb273
[TrimmableTypeMap] Pre-compile Mono.Android JCWs into mono.android-ty…
simonrozsival Jul 15, 2026
cbd1c05
[TrimmableTypeMap] Support reference-only assemblies + framework type…
simonrozsival Jul 15, 2026
0ac7bc0
[TrimmableTypeMap] App build: consume pre-generated Mono.Android typemap
simonrozsival Jul 15, 2026
b3d5711
[TrimmableTypeMap] Ship + merge pre-generated Mono.Android ACW map fo…
simonrozsival Jul 15, 2026
7b28317
[TrimmableTypeMap] Pre-generate Mono.Android + Java.Interop together;…
simonrozsival Jul 15, 2026
5e349c7
[TrimmableTypeMap] Fall back to normal scan for Debug NativeAOT (aggr…
simonrozsival Jul 15, 2026
f31eea5
Address code review feedback on pre-generated Mono.Android typemap
simonrozsival Jul 15, 2026
f039f94
Merge origin/main into pregenerated typemap work
simonrozsival Aug 19, 2026
5eed13f
Fix pregenerated typemap packaging and CoreCLR builds
simonrozsival Aug 19, 2026
90fbc3d
[TrimmableTypeMap] Skip redundant assembly reference scans
simonrozsival Aug 19, 2026
d8ec4f9
Revert "[TrimmableTypeMap] Skip redundant assembly reference scans"
simonrozsival Aug 19, 2026
5e3ceb7
Fix pre-generated typemap Java packaging
simonrozsival Aug 19, 2026
0ccfc85
Fix pre-generated typemap runtime handling
simonrozsival Aug 20, 2026
eb14959
Merge remote-tracking branch 'origin/main' into copilot/pr-12127-root…
simonrozsival Aug 20, 2026
085942a
Fix merged typemap test call
simonrozsival Aug 20, 2026
3386201
Include pre-generated framework Java classes
simonrozsival Aug 20, 2026
a227448
Ship trimmable framework Java wrappers
simonrozsival Aug 21, 2026
8aaa658
Do not package framework wrappers in libraries
simonrozsival Aug 21, 2026
d55cfea
Fix pre-generated typemap incrementality
simonrozsival Aug 21, 2026
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
<!--
Pre-generates the trimmable type map for Mono.Android at SDK build time (issue #10792).

App builds otherwise rescan the ~8000 Mono.Android types on every (Debug) build. Instead we
scan Mono.Android once here and ship the resulting typemap assemblies and Java Callable Wrappers
in the SDK pack. The typemap anchors on Java.Lang.Object (ForceSharedTypemapUniverse=true) to
coordinate aliases across Mono.Android and Java.Interop. Debug app builds can consume it because
their remaining typemaps use separate per-assembly universes. Release builds must instead scan the
complete app closure so shared-universe alias ownership includes application types. The root
_Microsoft.Android.TypeMaps assembly is NOT generated here (GenerateRootAssembly=false) — the
Debug app build emits it and references this pre-generated typemap under Java.Lang.Object.
-->
<Project>

<UsingTask TaskName="Xamarin.Android.Tasks.GenerateTrimmableTypeMap" AssemblyFile="$(MicrosoftAndroidSdkOutDir)Xamarin.Android.Build.Tasks.dll" />

<PropertyGroup>
<_PreBuiltTypeMapPackSubDir>data\prebuilt-typemap</_PreBuiltTypeMapPackSubDir>
<_PreBuiltTypeMapOutputDir>$(MicrosoftAndroidSdkPackDir)$(_PreBuiltTypeMapPackSubDir)\</_PreBuiltTypeMapOutputDir>
<!-- These DLLs are SDK runtime inputs consumed explicitly by the Android targets, not
compile-time references. NuGet otherwise warns that assemblies under data/ are outside
lib/, and this repository treats pack warnings as errors. -->
<NoWarn>$(NoWarn);NU5100</NoWarn>
<!-- Intermediate (not packaged): generated JCW .java and compiled .class files. -->
<_PreBuiltTypeMapIntDir>$([MSBuild]::NormalizeDirectory('$(MSBuildProjectDirectory)', 'obj', 'prebuilt-typemap'))</_PreBuiltTypeMapIntDir>
<_PreBuiltTypeMapJavaDir>$(_PreBuiltTypeMapIntDir)java\</_PreBuiltTypeMapJavaDir>
<_PreBuiltTypeMapAssembly>$(_PreBuiltTypeMapOutputDir)_Mono.Android.TypeMap.dll</_PreBuiltTypeMapAssembly>
<_PreBuiltTypeMapJavaInteropAssembly>$(_PreBuiltTypeMapOutputDir)_Java.Interop.TypeMap.dll</_PreBuiltTypeMapJavaInteropAssembly>
<_PreBuiltTypeMapAcwMap>$(_PreBuiltTypeMapOutputDir)mono.android-acw-map.txt</_PreBuiltTypeMapAcwMap>
<_PreBuiltTypeMapJavaFilesList>$(_PreBuiltTypeMapIntDir)java-files.txt</_PreBuiltTypeMapJavaFilesList>
<_PreBuiltTypeMapGenerationStamp>$(_PreBuiltTypeMapIntDir)_GeneratePreBuiltMonoAndroidTypeMap.stamp</_PreBuiltTypeMapGenerationStamp>
</PropertyGroup>

<!-- Generated files use content-based writes and can legitimately be older than the generator
inputs. Use a stamp for timestamp incrementality, but invalidate it whenever any real output
recorded by the previous generation pass is missing. -->
<Target Name="_InvalidatePreBuiltMonoAndroidTypeMapStampIfOutputsMissing">
<ItemGroup>
<_ExpectedPreBuiltTypeMapJavaFile Remove="@(_ExpectedPreBuiltTypeMapJavaFile)" />
<_ActualPreBuiltTypeMapJavaFile Remove="@(_ActualPreBuiltTypeMapJavaFile)" />
<_MissingPreBuiltTypeMapJavaFile Remove="@(_MissingPreBuiltTypeMapJavaFile)" />
<_UnexpectedPreBuiltTypeMapJavaFile Remove="@(_UnexpectedPreBuiltTypeMapJavaFile)" />
</ItemGroup>
<ReadLinesFromFile
File="$(_PreBuiltTypeMapJavaFilesList)"
Condition="Exists('$(_PreBuiltTypeMapJavaFilesList)')">
<Output TaskParameter="Lines" ItemName="_ExpectedPreBuiltTypeMapJavaFile" />
</ReadLinesFromFile>
<ItemGroup>
<_ActualPreBuiltTypeMapJavaFile Include="$(_PreBuiltTypeMapJavaDir)**\*.java" />
<_MissingPreBuiltTypeMapJavaFile Include="@(_ExpectedPreBuiltTypeMapJavaFile)"
Condition="!Exists('%(_ExpectedPreBuiltTypeMapJavaFile.Identity)')" />
<_UnexpectedPreBuiltTypeMapJavaFile Include="@(_ActualPreBuiltTypeMapJavaFile->'%(FullPath)')"
Exclude="@(_ExpectedPreBuiltTypeMapJavaFile)" />
</ItemGroup>
<Delete
Files="$(_PreBuiltTypeMapGenerationStamp)"
Condition="Exists('$(_PreBuiltTypeMapGenerationStamp)') and (!Exists('$(_PreBuiltTypeMapAssembly)') or !Exists('$(_PreBuiltTypeMapJavaInteropAssembly)') or !Exists('$(_PreBuiltTypeMapAcwMap)') or !Exists('$(_PreBuiltTypeMapJavaFilesList)') or '@(_MissingPreBuiltTypeMapJavaFile->Count())' != '0' or '@(_UnexpectedPreBuiltTypeMapJavaFile->Count())' != '0')" />
<ItemGroup>
<_ExpectedPreBuiltTypeMapJavaFile Remove="@(_ExpectedPreBuiltTypeMapJavaFile)" />
<_ActualPreBuiltTypeMapJavaFile Remove="@(_ActualPreBuiltTypeMapJavaFile)" />
<_MissingPreBuiltTypeMapJavaFile Remove="@(_MissingPreBuiltTypeMapJavaFile)" />
<_UnexpectedPreBuiltTypeMapJavaFile Remove="@(_UnexpectedPreBuiltTypeMapJavaFile)" />
</ItemGroup>
</Target>

<Target Name="_GeneratePreBuiltMonoAndroidTypeMap"
BeforeTargets="ConfigureLocalWorkload;_GenerateXASdkContent"
DependsOnTargets="_InvalidatePreBuiltMonoAndroidTypeMapStampIfOutputsMissing"
Inputs="$(_MonoAndroidNETDefaultOutDir)Mono.Android.dll;$(_MonoAndroidNETDefaultOutDir)Java.Interop.dll;$(MicrosoftAndroidSdkOutDir)Xamarin.Android.Build.Tasks.dll"
Outputs="$(_PreBuiltTypeMapGenerationStamp)">
<ItemGroup>
<!-- Scan Mono.Android and Java.Interop TOGETHER so their cross-assembly aliases (e.g.
java/lang/Object mapped by both Java.Lang.Object and Java.Interop.JavaObject) are
coordinated into a single primary + aliases, instead of colliding as duplicate keys in
the merged Java.Lang.Object universe at runtime. -->
<_PreBuiltTypeMapInput Include="$(_MonoAndroidNETDefaultOutDir)Mono.Android.dll" />
<_PreBuiltTypeMapInput Include="$(_MonoAndroidNETDefaultOutDir)Java.Interop.dll" />
<!-- Reference-only framework assemblies needed to resolve base types.
These are NOT scanned for peers; only @(_PreBuiltTypeMapInput) is. -->
<_PreBuiltTypeMapFramework Include="$(_MonoAndroidNETDefaultOutDir)*.dll"
Exclude="@(_PreBuiltTypeMapInput)" />
</ItemGroup>
<MakeDir Directories="$(_PreBuiltTypeMapOutputDir);$(_PreBuiltTypeMapJavaDir)" />
<GenerateTrimmableTypeMap
ResolvedAssemblies="@(_PreBuiltTypeMapInput)"
ResolvedFrameworkAssemblies="@(_PreBuiltTypeMapFramework)"
FrameworkAssemblyNames="@(_PreBuiltTypeMapFramework->'%(Filename)')"
OutputDirectory="$(_PreBuiltTypeMapOutputDir)"
JavaSourceOutputDirectory="$(_PreBuiltTypeMapJavaDir)"
AcwMapOutputFile="$(_PreBuiltTypeMapAcwMap)"
TargetFrameworkVersion="v$(DotNetTargetFrameworkVersion)"
ForceSharedTypemapUniverse="true"
GenerateRootAssembly="false">
<Output TaskParameter="GeneratedJavaFiles" ItemName="_GeneratedPreBuiltTypeMapJavaFile" />
</GenerateTrimmableTypeMap>
<WriteLinesToFile
File="$(_PreBuiltTypeMapJavaFilesList)"
Lines="@(_GeneratedPreBuiltTypeMapJavaFile->'%(FullPath)')"
Overwrite="true"
WriteOnlyWhenDifferent="true" />
<Touch Files="$(_PreBuiltTypeMapGenerationStamp)" AlwaysCreate="true" />
<ItemGroup>
<FileWrites Include="@(_GeneratedPreBuiltTypeMapJavaFile)" />
<FileWrites Include="$(_PreBuiltTypeMapJavaFilesList)" />
<FileWrites Include="$(_PreBuiltTypeMapGenerationStamp)" />
</ItemGroup>
</Target>

<PropertyGroup>
<_PreBuiltTypeMapJcwJar>$(_PreBuiltTypeMapOutputDir)mono.android-typemaps.jar</_PreBuiltTypeMapJcwJar>
<_PreBuiltTypeMapJcwClassesDir>$(_PreBuiltTypeMapIntDir)jcw-classes\</_PreBuiltTypeMapJcwClassesDir>
<_PreBuiltTypeMapJcwSourceList>$(_PreBuiltTypeMapIntDir)jcw-sources.txt</_PreBuiltTypeMapJcwSourceList>
<_PreBuiltTypeMapAndroidJar>$(AndroidSdkDirectory)\platforms\android-$(AndroidPlatformId)\android.jar</_PreBuiltTypeMapAndroidJar>
<_PreBuiltTypeMapMonoAndroidJar>$(_MonoAndroidNETDefaultOutDir)mono.android.jar</_PreBuiltTypeMapMonoAndroidJar>
<_PreBuiltTypeMapRuntimeJar>$(MicrosoftAndroidSdkOutDir)java_runtime.jar</_PreBuiltTypeMapRuntimeJar>
</PropertyGroup>

<!-- Compile the generated Java Callable Wrappers into a jar shipped in the SDK pack. These
wrappers use the trimmable runtime registration path and cannot be replaced by the legacy
wrappers from mono.android.jar, which call TypeManager.n_activate. -->
<Target Name="_CompilePreBuiltMonoAndroidTypeMapJcwJarInputs"
DependsOnTargets="_GeneratePreBuiltMonoAndroidTypeMap">
<ItemGroup>
<_PreBuiltTypeMapJavaFile Remove="@(_PreBuiltTypeMapJavaFile)" />
</ItemGroup>
<ReadLinesFromFile File="$(_PreBuiltTypeMapJavaFilesList)">
<Output TaskParameter="Lines" ItemName="_PreBuiltTypeMapJavaFile" />
</ReadLinesFromFile>
</Target>

<Target Name="_CompilePreBuiltMonoAndroidTypeMapJcwJar"
BeforeTargets="ConfigureLocalWorkload;_GenerateXASdkContent"
DependsOnTargets="_CompilePreBuiltMonoAndroidTypeMapJcwJarInputs"
Inputs="$(_PreBuiltTypeMapGenerationStamp);$(_PreBuiltTypeMapJavaFilesList);@(_PreBuiltTypeMapJavaFile);$(_PreBuiltTypeMapAndroidJar);$(_PreBuiltTypeMapMonoAndroidJar);$(_PreBuiltTypeMapRuntimeJar)"
Outputs="$(_PreBuiltTypeMapJcwJar)">
<RemoveDir Directories="$(_PreBuiltTypeMapJcwClassesDir)" />
<MakeDir Directories="$(_PreBuiltTypeMapJcwClassesDir)" />
<WriteLinesToFile File="$(_PreBuiltTypeMapJcwSourceList)" Lines="@(_PreBuiltTypeMapJavaFile)" Overwrite="true" />
<Exec Command="&quot;$(JavaCPath)&quot; -source $(JavacSourceVersion) -target $(JavacTargetVersion) -nowarn -d &quot;$(_PreBuiltTypeMapJcwClassesDir.TrimEnd('\'))&quot; -classpath &quot;$(_PreBuiltTypeMapAndroidJar)&quot;$(PathSeparator)&quot;$(_PreBuiltTypeMapMonoAndroidJar)&quot;$(PathSeparator)&quot;$(_PreBuiltTypeMapRuntimeJar)&quot; @&quot;$(_PreBuiltTypeMapJcwSourceList)&quot;" />
<Exec Command="&quot;$(JarPath)&quot; cf &quot;$(_PreBuiltTypeMapJcwJar)&quot; -C &quot;$(_PreBuiltTypeMapJcwClassesDir.TrimEnd('\'))&quot; ." />
</Target>

<Target Name="_AddPreBuiltMonoAndroidTypeMapToPackage"
BeforeTargets="_GenerateXASdkContent"
DependsOnTargets="_GeneratePreBuiltMonoAndroidTypeMap;_CompilePreBuiltMonoAndroidTypeMapJcwJar">
<ItemGroup>
<_PreBuiltTypeMapAllAssemblies Include="$(_PreBuiltTypeMapOutputDir)*.TypeMap.dll" />
<FilesToPackage Include="@(_PreBuiltTypeMapAllAssemblies)" TargetPath="$(_PreBuiltTypeMapPackSubDir)" />
<FilesToPackage Include="$(_PreBuiltTypeMapJcwJar)" TargetPath="$(_PreBuiltTypeMapPackSubDir)" />
<FilesToPackage Include="$(_PreBuiltTypeMapAcwMap)" TargetPath="$(_PreBuiltTypeMapPackSubDir)" />
</ItemGroup>
</Target>

</Project>
2 changes: 2 additions & 0 deletions build-tools/create-packs/Microsoft.Android.Sdk.proj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ core workload SDK packs imported by WorkloadManifest.targets.
<Sdk Name="Microsoft.DotNet.SharedFramework.Sdk" Version="$(MicrosoftDotNetBuildTasksFeedPackageVersionNet10)" />
<UsingTask AssemblyFile="$(BootstrapTasksAssembly)" TaskName="Xamarin.Android.Tools.BootstrapTasks.GenerateUnixFilePermissions" TaskFactory="TaskHostFactory" Runtime="NET" />

<Import Project="Microsoft.Android.Sdk.TrimmableTypeMap.targets" />

<PropertyGroup>
<!-- Use stable TFM since CI only has the stable .NET SDK installed -->
<TargetFramework>$(DotNetStableTargetFramework)</TargetFramework>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@

namespace Microsoft.Android.Sdk.TrimmableTypeMap;

public readonly record struct AssemblyInput (string Name, string Path, PEReader Reader);
/// <param name="ScanForPeers">
/// When true (default) the assembly is scanned and its Java peers are emitted into a typemap.
/// When false the assembly is only indexed for base-type resolution (e.g. Mono.Android on the app
/// build, whose typemap is pre-generated at SDK build time, issue #10792) and no peers are emitted.
/// </param>
public readonly record struct AssemblyInput (string Name, string Path, PEReader Reader, bool ScanForPeers = true);
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,16 @@ public RootTypeMapAssemblyGenerator (Version systemRuntimeVersion)
/// <param name="stream">Stream to write the output PE to.</param>
/// <param name="assemblyName">Optional assembly name (defaults to _Microsoft.Android.TypeMaps).</param>
/// <param name="moduleName">Optional module name for the PE metadata.</param>
public void Generate (IReadOnlyList<string> perAssemblyTypeMapNames, bool useSharedTypemapUniverse, Stream stream, string? assemblyName = null, string? moduleName = null)
/// <param name="sharedFrameworkTypeMapNames">
/// Names of pre-generated framework per-assembly typemaps (e.g. <c>_Mono.Android.TypeMap</c>,
/// produced at SDK build time, issue #10792) that always use <c>Java.Lang.Object</c> as their
/// universe anchor regardless of <paramref name="useSharedTypemapUniverse"/>. They are emitted as
/// <c>[assembly: TypeMapAssemblyTarget&lt;Java.Lang.Object&gt;("name")]</c> so the runtime loads
/// them into the <c>Java.Lang.Object</c> universe: in shared mode they merge into the single
/// app universe; in aggregate mode the loader adds the <c>Java.Lang.Object</c> universe alongside
/// the app's per-assembly universes.
/// </param>
public void Generate (IReadOnlyList<string> perAssemblyTypeMapNames, bool useSharedTypemapUniverse, Stream stream, string? assemblyName = null, string? moduleName = null, IReadOnlyList<string>? sharedFrameworkTypeMapNames = null)
{
if (perAssemblyTypeMapNames is null) {
throw new ArgumentNullException (nameof (perAssemblyTypeMapNames));
Expand Down Expand Up @@ -118,17 +127,28 @@ public void Generate (IReadOnlyList<string> perAssemblyTypeMapNames, bool useSha
EmitPerAssemblyUniverseAssemblyTargetAttributes (pe, perAssemblyTypeMapNames);
}

// Pre-generated framework typemaps (e.g. _Mono.Android.TypeMap) always live in the
// Java.Lang.Object universe, so reference them under that anchor regardless of mode.
var sharedFrameworkNames = sharedFrameworkTypeMapNames;
bool hasSharedFrameworkUniverse = sharedFrameworkNames is { Count: > 0 };
if (sharedFrameworkNames is { Count: > 0 }) {
var javaLangObjectHandle = pe.Metadata.AddTypeReference (pe.MonoAndroidRef,
pe.Metadata.GetOrAddString ("Java.Lang"),
pe.Metadata.GetOrAddString ("Object"));
EmitSharedUniverseAssemblyTargetAttributes (pe, javaLangObjectHandle, sharedFrameworkNames);
}

// Emit [assembly: IgnoresAccessChecksTo("...")] so TypeMapLoader.Initialize() can access
// internal types (TrimmableTypeMap and friends in Mono.Android, and private anchors
// in each per-assembly typemap DLL when aggregate universes or array maps are used).
// in each per-assembly typemap DLL when aggregate universes are used).
var accessTargets = new List<string> { "Mono.Android" };
if (!useSharedTypemapUniverse) {
accessTargets.AddRange (perAssemblyTypeMapNames);
}
pe.EmitIgnoresAccessChecksToAttribute (accessTargets);

// Emit TypeMapLoader class with Initialize() method
EmitTypeMapLoader (pe, anchorTypeHandle, perAssemblyTypeMapNames, useSharedTypemapUniverse, assemblyName);
EmitTypeMapLoader (pe, anchorTypeHandle, perAssemblyTypeMapNames, useSharedTypemapUniverse, assemblyName, hasSharedFrameworkUniverse);

pe.WritePE (stream);
}
Expand Down Expand Up @@ -176,7 +196,7 @@ static void EmitAssemblyTargetAttribute (PEAssemblyBuilder pe, MemberReferenceHa
pe.Metadata.AddCustomAttribute (EntityHandle.AssemblyDefinition, ctorRef, blobHandle);
}

static void EmitTypeMapLoader (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle, IReadOnlyList<string> perAssemblyTypeMapNames, bool useSharedTypemapUniverse, string assemblyName)
static void EmitTypeMapLoader (PEAssemblyBuilder pe, EntityHandle anchorTypeHandle, IReadOnlyList<string> perAssemblyTypeMapNames, bool useSharedTypemapUniverse, string assemblyName, bool hasSharedFrameworkUniverse = false)
{
var metadata = pe.Metadata;

Expand Down Expand Up @@ -214,13 +234,16 @@ static void EmitTypeMapLoader (PEAssemblyBuilder pe, EntityHandle anchorTypeHand
var externalDictTypeSpec = MakeIReadOnlyDictTypeSpec (pe, iReadOnlyDictOpenRef, systemTypeRef, keyIsString: true);

if (useSharedTypemapUniverse) {
// Single Java.Lang.Object universe. Pre-generated framework typemaps (if any) also
// anchor on Java.Lang.Object, so GetOrCreateExternalTypeMapping<Java.Lang.Object>()
// already merges them in via their TypeMapAssemblyTarget attributes — no extra universe.
var initializeRef = AddInitializeSingleNoArraysRef (pe, trimmableTypeMapRef, iReadOnlyDictOpenRef, systemTypeRef);
EmitInitializeWithSingleTypeMapNoArrays (pe, anchorTypeHandle, getExternalMemberRef, getProxyMemberRef, initializeRef, assemblyName);
} else {
var proxyDictTypeSpec = MakeIReadOnlyDictTypeSpec (pe, iReadOnlyDictOpenRef, systemTypeRef, keyIsString: false);
var initializeRef = AddInitializeAggregateNoArraysRef (pe, trimmableTypeMapRef, iReadOnlyDictOpenRef, systemTypeRef);
EmitInitializeWithAggregateTypeMapNoArrays (pe, perAssemblyTypeMapNames, getExternalMemberRef, getProxyMemberRef,
initializeRef, externalDictTypeSpec, proxyDictTypeSpec, iReadOnlyDictOpenRef, systemTypeRef, assemblyName);
initializeRef, externalDictTypeSpec, proxyDictTypeSpec, iReadOnlyDictOpenRef, systemTypeRef, assemblyName, hasSharedFrameworkUniverse);
}
}

Expand Down Expand Up @@ -251,18 +274,30 @@ static void EmitInitializeWithAggregateTypeMapNoArrays (PEAssemblyBuilder pe,
MemberReferenceHandle initializeRef,
TypeSpecificationHandle externalDictTypeSpec, TypeSpecificationHandle proxyDictTypeSpec,
TypeReferenceHandle iReadOnlyDictOpenRef, TypeReferenceHandle systemTypeRef,
string assemblyName)
string assemblyName,
bool hasSharedFrameworkUniverse = false)
{
var count = perAssemblyTypeMapNames.Count;
// When a pre-generated framework typemap is present (e.g. _Mono.Android.TypeMap), it lives in
// the Java.Lang.Object universe. Emit it as universe [0] (via
// GetOrCreate*TypeMapping<Java.Lang.Object>()), followed by the app's per-assembly universes.
var count = perAssemblyTypeMapNames.Count + (hasSharedFrameworkUniverse ? 1 : 0);

var getExternalSpecs = new EntityHandle [count];
var getProxySpecs = new EntityHandle [count];
for (int i = 0; i < count; i++) {
int offset = 0;
if (hasSharedFrameworkUniverse) {
var javaLangObjectRef = pe.Metadata.AddTypeReference (pe.MonoAndroidRef,
pe.Metadata.GetOrAddString ("Java.Lang"), pe.Metadata.GetOrAddString ("Object"));
getExternalSpecs [0] = MakeGenericMethodSpec (pe, getExternalMemberRef, javaLangObjectRef);
getProxySpecs [0] = MakeGenericMethodSpec (pe, getProxyMemberRef, javaLangObjectRef);
offset = 1;
}
for (int i = 0; i < perAssemblyTypeMapNames.Count; i++) {
var asmRef = pe.FindOrAddAssemblyRef (perAssemblyTypeMapNames [i]);
var perAsmAnchorRef = pe.Metadata.AddTypeReference (asmRef,
default, pe.Metadata.GetOrAddString ("__TypeMapAnchor"));
getExternalSpecs [i] = MakeGenericMethodSpec (pe, getExternalMemberRef, perAsmAnchorRef);
getProxySpecs [i] = MakeGenericMethodSpec (pe, getProxyMemberRef, perAsmAnchorRef);
getExternalSpecs [offset + i] = MakeGenericMethodSpec (pe, getExternalMemberRef, perAsmAnchorRef);
getProxySpecs [offset + i] = MakeGenericMethodSpec (pe, getProxyMemberRef, perAsmAnchorRef);
}

pe.EmitBody ("Initialize",
Expand Down
Loading
Loading