Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
Expand Up @@ -444,12 +444,12 @@ bool TryEmitExportParameterArgument (TrackedInstructionEncoder encoder, ExportPa
case ExportParameterKindInfo.XmlPullParser:
encoder.LoadArgument (argumentIndex);
encoder.LoadConstantI4 (0);
encoder.Call (_context.XmlPullParserReaderFromJniHandleRef, parameterCount: 2, returnsValue: true);
encoder.Call (_context.GetXmlPullParserReaderFromJniHandleRef (), parameterCount: 2, returnsValue: true);
return true;
case ExportParameterKindInfo.XmlResourceParser:
encoder.LoadArgument (argumentIndex);
encoder.LoadConstantI4 (0);
encoder.Call (_context.XmlResourceParserReaderFromJniHandleRef, parameterCount: 2, returnsValue: true);
encoder.Call (_context.GetXmlResourceParserReaderFromJniHandleRef (), parameterCount: 2, returnsValue: true);
return true;
default:
return false;
Expand Down Expand Up @@ -534,10 +534,10 @@ bool TryEmitExportParameterReturn (TrackedInstructionEncoder encoder, ExportPara
encoder.Call (_context.OutputStreamAdapterToLocalJniHandleRef, parameterCount: 1, returnsValue: true);
return true;
case ExportParameterKindInfo.XmlPullParser:
encoder.Call (_context.XmlReaderPullParserToLocalJniHandleRef, parameterCount: 1, returnsValue: true);
encoder.Call (_context.GetXmlReaderPullParserToLocalJniHandleRef (), parameterCount: 1, returnsValue: true);
return true;
case ExportParameterKindInfo.XmlResourceParser:
encoder.Call (_context.XmlReaderResourceParserToLocalJniHandleRef, parameterCount: 1, returnsValue: true);
encoder.Call (_context.GetXmlReaderResourceParserToLocalJniHandleRef (), parameterCount: 1, returnsValue: true);
return true;
default:
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ namespace Microsoft.Android.Sdk.TrimmableTypeMap;
/// </summary>
sealed class ExportMethodDispatchEmitterContext
{
readonly PEAssemblyBuilder _pe;

TypeReferenceHandle _systemXmlReaderRef;
MemberReferenceHandle _xmlPullParserReaderFromJniHandleRef;
MemberReferenceHandle _xmlResourceParserReaderFromJniHandleRef;
MemberReferenceHandle _xmlReaderPullParserToLocalJniHandleRef;
MemberReferenceHandle _xmlReaderResourceParserToLocalJniHandleRef;

ExportMethodDispatchEmitterContext (PEAssemblyBuilder pe)
{
_pe = pe;
}

public static ExportMethodDispatchEmitterContext Create (
PEAssemblyBuilder pe,
TypeReferenceHandle iJavaPeerableRef,
Expand All @@ -35,9 +48,6 @@ public static ExportMethodDispatchEmitterContext Create (
metadata.GetOrAddString ("System"), metadata.GetOrAddString ("Array"));
var systemStreamRef = metadata.AddTypeReference (pe.SystemRuntimeRef,
metadata.GetOrAddString ("System.IO"), metadata.GetOrAddString ("Stream"));
var systemXmlRef = pe.FindOrAddAssemblyRef ("System.Xml.ReaderWriter");
var systemXmlReaderRef = metadata.AddTypeReference (systemXmlRef,
metadata.GetOrAddString ("System.Xml"), metadata.GetOrAddString ("XmlReader"));
var inputStreamInvokerRef = metadata.AddTypeReference (pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("InputStreamInvoker"));
var outputStreamInvokerRef = metadata.AddTypeReference (pe.MonoAndroidRef,
Expand All @@ -46,14 +56,6 @@ public static ExportMethodDispatchEmitterContext Create (
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("InputStreamAdapter"));
var outputStreamAdapterRef = metadata.AddTypeReference (pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("OutputStreamAdapter"));
var xmlPullParserReaderRef = metadata.AddTypeReference (pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlPullParserReader"));
var xmlResourceParserReaderRef = metadata.AddTypeReference (pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlResourceParserReader"));
var xmlReaderPullParserRef = metadata.AddTypeReference (pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlReaderPullParser"));
var xmlReaderResourceParserRef = metadata.AddTypeReference (pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlReaderResourceParser"));
var charSequenceRef = metadata.AddTypeReference (pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("CharSequence"));
var iCharSequenceRef = metadata.AddTypeReference (pe.MonoAndroidRef,
Expand All @@ -71,8 +73,9 @@ public static ExportMethodDispatchEmitterContext Create (
var systemCollectionsICollectionRef = metadata.AddTypeReference (pe.SystemRuntimeRef,
metadata.GetOrAddString ("System.Collections"), metadata.GetOrAddString ("ICollection"));

return new ExportMethodDispatchEmitterContext {
return new ExportMethodDispatchEmitterContext (pe) {
IJavaObjectRef = iJavaObjectRef,
JniHandleOwnershipRef = jniHandleOwnershipRef,
GetTypeFromHandleRef = getTypeFromHandleRef,
JniEnvGetStringRef = pe.AddMemberRef (jniEnvRef, "GetString",
sig => sig.MethodSignature ().Parameters (2,
Expand Down Expand Up @@ -142,28 +145,6 @@ public static ExportMethodDispatchEmitterContext Create (
sig => sig.MethodSignature ().Parameters (1,
rt => rt.Type ().IntPtr (),
p => p.AddParameter ().Type ().Type (systemStreamRef, false))),
XmlPullParserReaderFromJniHandleRef = pe.AddMemberRef (xmlPullParserReaderRef, "FromJniHandle",
sig => sig.MethodSignature ().Parameters (2,
rt => rt.Type ().Type (systemXmlReaderRef, false),
p => {
p.AddParameter ().Type ().IntPtr ();
p.AddParameter ().Type ().Type (jniHandleOwnershipRef, true);
})),
XmlResourceParserReaderFromJniHandleRef = pe.AddMemberRef (xmlResourceParserReaderRef, "FromJniHandle",
sig => sig.MethodSignature ().Parameters (2,
rt => rt.Type ().Type (systemXmlReaderRef, false),
p => {
p.AddParameter ().Type ().IntPtr ();
p.AddParameter ().Type ().Type (jniHandleOwnershipRef, true);
})),
XmlReaderPullParserToLocalJniHandleRef = pe.AddMemberRef (xmlReaderPullParserRef, "ToLocalJniHandle",
sig => sig.MethodSignature ().Parameters (1,
rt => rt.Type ().IntPtr (),
p => p.AddParameter ().Type ().Type (systemXmlReaderRef, false))),
XmlReaderResourceParserToLocalJniHandleRef = pe.AddMemberRef (xmlReaderResourceParserRef, "ToLocalJniHandle",
sig => sig.MethodSignature ().Parameters (1,
rt => rt.Type ().IntPtr (),
p => p.AddParameter ().Type ().Type (systemXmlReaderRef, false))),
CharSequenceToLocalJniHandleRef = pe.AddMemberRef (charSequenceRef, "ToLocalJniHandle",
sig => sig.MethodSignature ().Parameters (1,
rt => rt.Type ().IntPtr (),
Expand Down Expand Up @@ -191,6 +172,89 @@ public static ExportMethodDispatchEmitterContext Create (
};
}

TypeReferenceHandle GetSystemXmlReaderRef ()
{
if (!_systemXmlReaderRef.IsNil) {
return _systemXmlReaderRef;
}

var metadata = _pe.Metadata;
var systemXmlRef = _pe.FindOrAddAssemblyRef ("System.Xml.ReaderWriter");
_systemXmlReaderRef = metadata.AddTypeReference (systemXmlRef,
metadata.GetOrAddString ("System.Xml"), metadata.GetOrAddString ("XmlReader"));
return _systemXmlReaderRef;
}

public MemberReferenceHandle GetXmlPullParserReaderFromJniHandleRef ()
{
if (!_xmlPullParserReaderFromJniHandleRef.IsNil) {
return _xmlPullParserReaderFromJniHandleRef;
}

var metadata = _pe.Metadata;
var xmlPullParserReaderRef = metadata.AddTypeReference (_pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlPullParserReader"));
_xmlPullParserReaderFromJniHandleRef = _pe.AddMemberRef (xmlPullParserReaderRef, "FromJniHandle",
sig => sig.MethodSignature ().Parameters (2,
rt => rt.Type ().Type (GetSystemXmlReaderRef (), false),
p => {
p.AddParameter ().Type ().IntPtr ();
p.AddParameter ().Type ().Type (JniHandleOwnershipRef, true);
}));
return _xmlPullParserReaderFromJniHandleRef;
}

public MemberReferenceHandle GetXmlResourceParserReaderFromJniHandleRef ()
{
if (!_xmlResourceParserReaderFromJniHandleRef.IsNil) {
return _xmlResourceParserReaderFromJniHandleRef;
}

var metadata = _pe.Metadata;
var xmlResourceParserReaderRef = metadata.AddTypeReference (_pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlResourceParserReader"));
_xmlResourceParserReaderFromJniHandleRef = _pe.AddMemberRef (xmlResourceParserReaderRef, "FromJniHandle",
sig => sig.MethodSignature ().Parameters (2,
rt => rt.Type ().Type (GetSystemXmlReaderRef (), false),
p => {
p.AddParameter ().Type ().IntPtr ();
p.AddParameter ().Type ().Type (JniHandleOwnershipRef, true);
}));
return _xmlResourceParserReaderFromJniHandleRef;
}

public MemberReferenceHandle GetXmlReaderPullParserToLocalJniHandleRef ()
{
if (!_xmlReaderPullParserToLocalJniHandleRef.IsNil) {
return _xmlReaderPullParserToLocalJniHandleRef;
}

var metadata = _pe.Metadata;
var xmlReaderPullParserRef = metadata.AddTypeReference (_pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlReaderPullParser"));
_xmlReaderPullParserToLocalJniHandleRef = _pe.AddMemberRef (xmlReaderPullParserRef, "ToLocalJniHandle",
sig => sig.MethodSignature ().Parameters (1,
rt => rt.Type ().IntPtr (),
p => p.AddParameter ().Type ().Type (GetSystemXmlReaderRef (), false)));
return _xmlReaderPullParserToLocalJniHandleRef;
}

public MemberReferenceHandle GetXmlReaderResourceParserToLocalJniHandleRef ()
{
if (!_xmlReaderResourceParserToLocalJniHandleRef.IsNil) {
return _xmlReaderResourceParserToLocalJniHandleRef;
}

var metadata = _pe.Metadata;
var xmlReaderResourceParserRef = metadata.AddTypeReference (_pe.MonoAndroidRef,
metadata.GetOrAddString ("Android.Runtime"), metadata.GetOrAddString ("XmlReaderResourceParser"));
_xmlReaderResourceParserToLocalJniHandleRef = _pe.AddMemberRef (xmlReaderResourceParserRef, "ToLocalJniHandle",
sig => sig.MethodSignature ().Parameters (1,
rt => rt.Type ().IntPtr (),
p => p.AddParameter ().Type ().Type (GetSystemXmlReaderRef (), false)));
return _xmlReaderResourceParserToLocalJniHandleRef;
}

public required TypeReferenceHandle IJavaObjectRef { get; init; }
public required MemberReferenceHandle GetTypeFromHandleRef { get; init; }
public required MemberReferenceHandle JniEnvGetStringRef { get; init; }
Expand All @@ -204,10 +268,6 @@ public static ExportMethodDispatchEmitterContext Create (
public required MemberReferenceHandle OutputStreamInvokerFromJniHandleRef { get; init; }
public required MemberReferenceHandle InputStreamAdapterToLocalJniHandleRef { get; init; }
public required MemberReferenceHandle OutputStreamAdapterToLocalJniHandleRef { get; init; }
public required MemberReferenceHandle XmlPullParserReaderFromJniHandleRef { get; init; }
public required MemberReferenceHandle XmlResourceParserReaderFromJniHandleRef { get; init; }
public required MemberReferenceHandle XmlReaderPullParserToLocalJniHandleRef { get; init; }
public required MemberReferenceHandle XmlReaderResourceParserToLocalJniHandleRef { get; init; }
public required MemberReferenceHandle CharSequenceToLocalJniHandleRef { get; init; }
public required MemberReferenceHandle JavaListToLocalJniHandleRef { get; init; }
public required MemberReferenceHandle JavaDictionaryToLocalJniHandleRef { get; init; }
Expand All @@ -225,4 +285,5 @@ public static ExportMethodDispatchEmitterContext Create (
public required MemberReferenceHandle BeginMarshalMethodRef { get; init; }
public required MemberReferenceHandle EndMarshalMethodRef { get; init; }
public required MemberReferenceHandle OnUserUnhandledExceptionRef { get; init; }
public required TypeReferenceHandle JniHandleOwnershipRef { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,35 @@ public void Generate_HasRequiredAssemblyReferences ()
Assert.Contains ("System.Runtime.InteropServices", asmRefs);
}

[Fact]
public void Generate_ExportWithoutXmlMarshalling_DoesNotReferenceSystemXml ()
{
var peer = ScanFixtures ().Single (p => p.JavaName == "my/app/ExportExample");
using var stream = GenerateAssembly (new [] { peer });
using var pe = new PEReader (stream);
var reader = pe.GetMetadataReader ();
var asmRefs = reader.AssemblyReferences
.Select (h => reader.GetString (reader.GetAssemblyReference (h).Name))
.ToList ();

Assert.DoesNotContain ("System.Xml.ReaderWriter", asmRefs);
Assert.DoesNotContain ("System.Private.Xml", asmRefs);
}

[Fact]
public void Generate_ExportWithXmlMarshalling_ReferencesSystemXml ()
{
var peer = ScanFixtures ().Single (p => p.JavaName == "my/app/ExportMarshallingShapes");
using var stream = GenerateAssembly (new [] { peer });
using var pe = new PEReader (stream);
var reader = pe.GetMetadataReader ();
var asmRefs = reader.AssemblyReferences
.Select (h => reader.GetString (reader.GetAssemblyReference (h).Name))
.ToList ();

Assert.Contains ("System.Xml.ReaderWriter", asmRefs);
}

[Fact]
public void Generate_InheritedGenericBaseCallback_UsesValueTypeGenericArgument ()
{
Expand Down