Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

Commit 71afce5

Browse files
jpobstjonpryor
authored andcommitted
[generator] Support Kotlin's unsigned types (#539)
Fixes: #525 Context: dotnet/android#4054 Context: https://github.com/Kotlin/KEEP/blob/13b67668ccc5b4741ecc37d0dd050fd77227c035/proposals/unsigned-types.md Context: https://kotlinlang.org/docs/reference/basic-types.html#unsigned-integers Another place where Kotlin makes use of "name mangling" -- see also commit f3553f4 -- is in the use of unsigned types such as `UInt`. At the JVM ABI level, Kotlin treats unsigned types as their signed counterparts, e.g. `kotlin.UInt` is an `int` and `kotlin.UIntArray` is an `int[]`: // Kotlin public class Example { public fun value(value: UInt) : UInt { return value } public fun array(value: UIntArray) : UIntArray { return value } } // `javap` output: public final class Example { public final int value-WZ4Q5Ns(int); public final int[] array--ajY-9A(int[]); } Kotlin uses Java Annotations to determine whether a parameter or return type is actually an unsigned type instead of a signed type. Update `Xamarin.Android.Tools.Bytecode` and `generator` to bind e.g.: * `kotlin.UInt` as `System.UInt32` * `kotlin.UIntArray` as a `System.UInt32[]` and likewise for the other unsigned types `ushort`, `ulong`, `ubyte`. In order to do this, we pretend that they are native Java types and just translate a few places where we need to tell Java the real type. ~~ Xamarin.Android.Tools.Bytecode / class-parse ~~ When we read the Kotlin metadata in the Java bytecode, if we come across one of these types we store it within an additional `FieldInfo.KotlinType` property that we can access later. When we are generating the XML we check this additional flag and if it's one of our types we emit it instead of the native Java type. For example: <method abstract="false" deprecated="not deprecated" final="false" name="unsignedAbstractMethod-WZ4Q5Ns" native="false" return="uint" jni-return="I" static="false" synchronized="false" visibility="public" bridge="false" synthetic="false" jni-signature="(I)I"> <parameter name="value" type="uint" jni-type="I" /> </method> Here we see that even though `@jni-return` is `I` -- meaning `int` -- the `@return` property is `uint`. Likewise `parameter/@jni-type` and `parameter/@type`. The JNI ABI is `int`, but we bind in C# as `uint`. ~~ ApiXmlAdjuster ~~ Update `JavaTypeReference` to contain unsigned types: UInt = new JavaTypeReference ("uint"); UShort = new JavaTypeReference ("ushort"); ULong = new JavaTypeReference ("ulong"); UByte = new JavaTypeReference ("ubyte"); ~~ generator ~~ `generator` has the 4 new types added to the `SymbolTable` as `SimpleSymbols`: AddType (new SimpleSymbol ("0", "uint", "uint", "I", returnCast: "(uint)")); AddType (new SimpleSymbol ("0", "ushort", "ushort", "S", returnCast: "(ushort)")); AddType (new SimpleSymbol ("0", "ulong", "ulong", "J", returnCast: "(ulong)")); AddType (new SimpleSymbol ("0", "ubyte", "byte", "B", returnCast: "(byte)")); There are 2 fixups we have to make because we use `GetIntValue(...)`, etc. instead of having unsigned versions: * Override name of which method to call, e.g.: `GetIntValue()` instead of `GetUintValue()`. * Cast the `int` value returned to `uint`. This is accomplished via the new `ISymbol.ReturnCast` property. ~~ A Note On API Compatibility ~~ Bindings which use Kotlin Unsigned Types will *only* work on Xamarin.Android 10.2.0 or later ("Visual Studio 16.5"). The problem is that while we *can* emit C# source code which will *compile* against older versions of Xamarin.Android, if they use arrays they will not *run* under older versions of Xamarin.Android. For example, imagine this binding code for the above Kotlin `Example.array()` method: // C# Binding of Example.array() partial class Example { public unsafe uint[] Array(uint[] value) { const string __id = "array--ajY-9A.([I)[I"; IntPtr native_value = JNIEnv.NewArray ((int[]) (object) value); // Works!...ish? JniArgumentValue* __args = stackalloc JniArgumentValue [1]; __args [0] = new JniArgumentValue (native_value); JniObjectReference r = _members.InstanceMethods.InvokeVirtualIntMethod (__id, this, __args); return (uint[]) JNIEnv.GetArray (r.Handle, JniHandleOwnership.DoNotTransfer, typeof (uint)); } } That could conceivably *compile* against older Xamarin.Android versions. However, that cannot *run* against older Xamarin.Android versions, as *eventually* `JNIEnv.GetArray()` will hit some dictionaries to determine how to marshal `IntPtr` to a `uint[]`, at which point things will fail because there is no such mapping *until* Xamarin.Android 10.2.0. We feel that a "hard" ABI requirement will have more "graceful" failure conditions than a solution which doesn't add ABI requirements. In this case, if you create a Kotlin library binding which exposes unsigned types, attempting to build an app in Release configuration against older Xamarin.Android versions will result in a linker error, as the required `JNIEnv` methods will not be resolvable.
1 parent f26bc27 commit 71afce5

44 files changed

Lines changed: 877 additions & 57 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,16 @@ static string GetPrimitiveClass (Type type)
232232
return"F";
233233
if(type==typeof(int))
234234
return"I";
235+
if(type==typeof(uint))
236+
return"I";
235237
if(type==typeof(long))
236238
return"J";
239+
if(type==typeof(ulong))
240+
return"J";
237241
if(type==typeof(short))
238242
return"S";
243+
if(type==typeof(ushort))
244+
return"S";
239245
if(type==typeof(bool))
240246
return"Z";
241247
returnnull;

‎src/Java.Interop/Java.Interop/JniArgumentValue.cs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public JniArgumentValue (sbyte value)
3434
b=value;
3535
}
3636

37+
publicJniArgumentValue(bytevalue):this((sbyte)value){}
38+
3739
publicJniArgumentValue(charvalue)
3840
{
3941
this=newJniArgumentValue();
@@ -46,18 +48,24 @@ public JniArgumentValue (short value)
4648
s=value;
4749
}
4850

51+
publicJniArgumentValue(ushortvalue):this((short)value){}
52+
4953
publicJniArgumentValue(intvalue)
5054
{
5155
this=newJniArgumentValue();
5256
i=value;
5357
}
5458

59+
publicJniArgumentValue(uintvalue):this((int)value){}
60+
5561
publicJniArgumentValue(longvalue)
5662
{
5763
this=newJniArgumentValue();
5864
j=value;
5965
}
6066

67+
publicJniArgumentValue(ulongvalue):this((long)value){}
68+
6169
publicJniArgumentValue(floatvalue)
6270
{
6371
this=newJniArgumentValue();

‎src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeReference.cs‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ public class JavaTypeReference
1616
publicstaticreadonlyJavaTypeReferenceFloat;
1717
publicstaticreadonlyJavaTypeReferenceDouble;
1818
publicstaticreadonlyJavaTypeReferenceGenericWildcard;
19-
19+
publicstaticreadonlyJavaTypeReferenceUInt;
20+
publicstaticreadonlyJavaTypeReferenceUShort;
21+
publicstaticreadonlyJavaTypeReferenceULong;
22+
publicstaticreadonlyJavaTypeReferenceUByte;
23+
2024
internalstaticJavaTypeReferenceGetSpecialType(stringname)
2125
{
2226
switch(name){
@@ -29,6 +33,10 @@ internal static JavaTypeReference GetSpecialType (string name)
2933
case"long":returnLong;
3034
case"float":returnFloat;
3135
case"double":returnDouble;
36+
case"uint":returnUInt;
37+
case"ushort":returnUShort;
38+
case"ulong":returnULong;
39+
case"ubyte":returnUByte;
3240
case"?":returnGenericWildcard;
3341
}
3442
returnnull;
@@ -46,8 +54,12 @@ static JavaTypeReference ()
4654
Float=newJavaTypeReference("float");
4755
Double=newJavaTypeReference("double");
4856
GenericWildcard=newJavaTypeReference("?");
57+
UInt=newJavaTypeReference("uint");
58+
UShort=newJavaTypeReference("ushort");
59+
ULong=newJavaTypeReference("ulong");
60+
UByte=newJavaTypeReference("ubyte");
4961
}
50-
62+
5163
JavaTypeReference(stringspecialName)
5264
{
5365
SpecialName=specialName;

‎src/Xamarin.Android.Tools.Bytecode/Fields.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public sealed class FieldInfo {
3333
publicConstantPoolConstantPool{get;privateset;}
3434
publicFieldAccessFlagsAccessFlags{get;privateset;}
3535
publicAttributeCollectionAttributes{get;privateset;}
36+
publicstringKotlinType{get;set;}
3637

3738
publicFieldInfo(ConstantPoolconstantPool,Streamstream)
3839
{

‎src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinClassMetadata.cs‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
usingSystem;
22
usingSystem.Collections.Generic;
3+
usingSystem.Diagnostics;
34
usingSystem.Linq;
45
usingSystem.Text;
56
usingorg.jetbrains.kotlin.metadata.jvm;
7+
usingProtoBuf;
68
usingType=org.jetbrains.kotlin.metadata.jvm.Type;
79

810
namespaceXamarin.Android.Tools.Bytecode
911
{
12+
// https://github.com/JetBrains/kotlin/blob/master/core/metadata.jvm/src/jvm_metadata.proto
1013
publicclassKotlinFile
1114
{
1215
publicList<KotlinFunction>Functions{get;set;}
@@ -220,6 +223,8 @@ internal static KotlinExpression FromProtobuf (Expression exp, JvmNameResolver r
220223
publicclassKotlinFunction:KotlinMethodBase
221224
{
222225
publicstringName{get;set;}
226+
publicstringJvmName{get;set;}
227+
publicstringJvmSignature{get;set;}
223228
publicKotlinFunctionFlagsFlags{get;set;}
224229
publicKotlinTypeReturnType{get;set;}
225230
publicintReturnTypeId{get;set;}
@@ -235,9 +240,13 @@ internal static KotlinFunction FromProtobuf (Function f, JvmNameResolver resolve
235240
if(fisnull)
236241
returnnull;
237242

243+
varsig=Extensible.GetValue<JvmMethodSignature>(f,100);
244+
238245
returnnewKotlinFunction{
239246
Flags=(KotlinFunctionFlags)f.Flags,
240247
Name=resolver.GetString(f.Name),
248+
JvmName=resolver.GetString((sig?.Name??0)>0?sig.Name:f.Name),
249+
JvmSignature=sigisnull?null:resolver.GetString(sig.Desc),
241250
ReturnType=KotlinType.FromProtobuf(f.ReturnType,resolver),
242251
ReturnTypeId=f.ReturnTypeId,
243252
ReceiverType=KotlinType.FromProtobuf(f.ReceiverType,resolver),

‎src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinFixups.cs‎

Lines changed: 71 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,15 @@ public static void Fixup (IList<ClassFile> classes)
4545
FixupJavaMethods(c.Methods);
4646

4747
foreach(varmetinmetadata.Functions)
48-
FixupFunction(FindJavaMethod(class_metadata,met,c),met,class_metadata);
48+
FixupFunction(FindJavaMethod(metadata,met,c),met,class_metadata);
4949

5050
foreach(varpropinmetadata.Properties){
51-
vargetter=FindJavaPropertyGetter(class_metadata,prop,c);
52-
varsetter=FindJavaPropertySetter(class_metadata,prop,c);
51+
vargetter=FindJavaPropertyGetter(metadata,prop,c);
52+
varsetter=FindJavaPropertySetter(metadata,prop,c);
5353

5454
FixupProperty(getter,setter,prop);
55+
56+
FixupField(FindJavaFieldProperty(metadata,prop,c),prop);
5557
}
5658

5759
}catch(Exceptionex){
@@ -96,7 +98,6 @@ static void FixupConstructor (MethodInfo method, KotlinConstructor metadata)
9698
Log.Debug($"Kotlin: Hiding internal constructor {method.DeclaringType?.ThisClass.Name.Value} - {metadata.GetSignature()}");
9799
method.AccessFlags=MethodAccessFlags.Private;
98100
}
99-
100101
}
101102

102103
staticvoidFixupFunction(MethodInfomethod,KotlinFunctionmetadata,KotlinClasskotlinClass)
@@ -111,18 +112,24 @@ static void FixupFunction (MethodInfo method, KotlinFunction metadata, KotlinCla
111112
return;
112113
}
113114

114-
// Kotlin provides actual parameter names
115115
varjava_parameters=method.GetFilteredParameters();
116116

117117
for(vari=0;i<java_parameters.Length;i++){
118118
varjava_p=java_parameters[i];
119119
varkotlin_p=metadata.ValueParameters[i];
120120

121+
// Kotlin provides actual parameter names
121122
if(TypesMatch(java_p.Type,kotlin_p.Type,kotlinClass)&&java_p.IsUnnamedParameter()&&!kotlin_p.IsUnnamedParameter()){
122123
Log.Debug($"Kotlin: Renaming parameter {method.DeclaringType?.ThisClass.Name.Value} - {method.Name} - {java_p.Name} -> {kotlin_p.Name}");
123124
java_p.Name=kotlin_p.Name;
124125
}
126+
127+
// Handle erasure of Kotlin unsigned types
128+
java_p.KotlinType=GetKotlinType(java_p.Type.TypeSignature,kotlin_p.Type.ClassName);
125129
}
130+
131+
// Handle erasure of Kotlin unsigned types
132+
method.KotlinReturnType=GetKotlinType(method.ReturnType.TypeSignature,metadata.ReturnType.ClassName);
126133
}
127134

128135
staticvoidFixupExtensionMethod(MethodInfomethod)
@@ -158,16 +165,32 @@ static void FixupProperty (MethodInfo getter, MethodInfo setter, KotlinProperty
158165
return;
159166
}
160167

168+
// Handle erasure of Kotlin unsigned types
169+
if(getter!=null)
170+
getter.KotlinReturnType=GetKotlinType(getter.ReturnType.TypeSignature,metadata.ReturnType.ClassName);
171+
161172
if(setter!=null){
162173
varsetter_parameter=setter.GetParameters().First();
163174

164-
if(setter_parameter.IsUnnamedParameter()){
175+
if(setter_parameter.IsUnnamedParameter()||setter_parameter.Name=="<set-?>"){
165176
Log.Debug($"Kotlin: Renaming setter parameter {setter.DeclaringType?.ThisClass.Name.Value} - {setter.Name} - {setter_parameter.Name} -> value");
166177
setter_parameter.Name="value";
167178
}
179+
180+
// Handle erasure of Kotlin unsigned types
181+
setter_parameter.KotlinType=GetKotlinType(setter_parameter.Type.TypeSignature,metadata.ReturnType.ClassName);
168182
}
169183
}
170184

185+
staticvoidFixupField(FieldInfofield,KotlinPropertymetadata)
186+
{
187+
if(fieldisnull)
188+
return;
189+
190+
// Handle erasure of Kotlin unsigned types
191+
field.KotlinType=GetKotlinType(field.Descriptor,metadata.ReturnType.ClassName);
192+
}
193+
171194
staticMethodInfoFindJavaConstructor(KotlinClasskotlinClass,KotlinConstructorconstructor,ClassFileklass)
172195
{
173196
varall_constructors=klass.Methods.Where(method =>method.Name=="<init>"||method.Name=="<clinit>");
@@ -181,16 +204,16 @@ static MethodInfo FindJavaConstructor (KotlinClass kotlinClass, KotlinConstructo
181204
returnnull;
182205
}
183206

184-
staticMethodInfoFindJavaMethod(KotlinClasskotlinClass,KotlinFunctionfunction,ClassFileklass)
207+
staticMethodInfoFindJavaMethod(KotlinFilekotlinFile,KotlinFunctionfunction,ClassFileklass)
185208
{
186-
varpossible_methods=klass.Methods.Where(method =>method.GetMethodNameWithoutSuffix()==function.Name&&
209+
varpossible_methods=klass.Methods.Where(method =>method.Name==function.JvmName&&
187210
method.GetFilteredParameters().Length==function.ValueParameters.Count);
188211

189212
foreach(varmethodinpossible_methods){
190-
if(!TypesMatch(method.ReturnType,function.ReturnType,kotlinClass))
213+
if(!TypesMatch(method.ReturnType,function.ReturnType,kotlinFile))
191214
continue;
192215

193-
if(!ParametersMatch(kotlinClass,method,function.ValueParameters))
216+
if(!ParametersMatch(kotlinFile,method,function.ValueParameters))
194217
continue;
195218

196219
returnmethod;
@@ -199,7 +222,15 @@ static MethodInfo FindJavaMethod (KotlinClass kotlinClass, KotlinFunction functi
199222
returnnull;
200223
}
201224

202-
staticMethodInfoFindJavaPropertyGetter(KotlinClasskotlinClass,KotlinPropertyproperty,ClassFileklass)
225+
staticFieldInfoFindJavaFieldProperty(KotlinFilekotlinClass,KotlinPropertyproperty,ClassFileklass)
226+
{
227+
varpossible_methods=klass.Fields.Where(field =>field.Name==property.Name&&
228+
TypesMatch(newTypeInfo(field.Descriptor,field.Descriptor),property.ReturnType,kotlinClass));
229+
230+
returnpossible_methods.FirstOrDefault();
231+
}
232+
233+
staticMethodInfoFindJavaPropertyGetter(KotlinFilekotlinClass,KotlinPropertyproperty,ClassFileklass)
203234
{
204235
varpossible_methods=klass.Methods.Where(method =>(string.Compare(method.GetMethodNameWithoutSuffix(),$"get{property.Name}",true)==0||
205236
string.Compare(method.GetMethodNameWithoutSuffix(),property.Name,true)==0)&&
@@ -209,7 +240,7 @@ static MethodInfo FindJavaPropertyGetter (KotlinClass kotlinClass, KotlinPropert
209240
returnpossible_methods.FirstOrDefault();
210241
}
211242

212-
staticMethodInfoFindJavaPropertySetter(KotlinClasskotlinClass,KotlinPropertyproperty,ClassFileklass)
243+
staticMethodInfoFindJavaPropertySetter(KotlinFilekotlinClass,KotlinPropertyproperty,ClassFileklass)
213244
{
214245
varpossible_methods=klass.Methods.Where(method =>string.Compare(method.GetMethodNameWithoutSuffix(),$"set{property.Name}",true)==0&&
215246
property.ReturnType!=null&&
@@ -219,7 +250,7 @@ static MethodInfo FindJavaPropertySetter (KotlinClass kotlinClass, KotlinPropert
219250
returnpossible_methods.FirstOrDefault();
220251
}
221252

222-
staticboolParametersMatch(KotlinClasskotlinClass,MethodInfomethod,List<KotlinValueParameter>kotlinParameters)
253+
staticboolParametersMatch(KotlinFilekotlinClass,MethodInfomethod,List<KotlinValueParameter>kotlinParameters)
223254
{
224255
varjava_parameters=method.GetFilteredParameters();
225256

@@ -237,13 +268,13 @@ static bool ParametersMatch (KotlinClass kotlinClass, MethodInfo method, List<Ko
237268
returntrue;
238269
}
239270

240-
staticboolTypesMatch(TypeInfojavaType,KotlinTypekotlinType,KotlinClasskotlinClass)
271+
staticboolTypesMatch(TypeInfojavaType,KotlinTypekotlinType,KotlinFilekotlinFile)
241272
{
242273
// Generic type
243274
if(!string.IsNullOrWhiteSpace(kotlinType.TypeParameterName)&&$"T{kotlinType.TypeParameterName};"==javaType.TypeSignature)
244275
returntrue;
245276

246-
if(javaType.BinaryName==KotlinUtilities.ConvertKotlinTypeSignature(kotlinType,kotlinClass))
277+
if(javaType.BinaryName==KotlinUtilities.ConvertKotlinTypeSignature(kotlinType,kotlinFile))
247278
returntrue;
248279

249280
// Could be a generic type erasure
@@ -253,17 +284,40 @@ static bool TypesMatch (TypeInfo javaType, KotlinType kotlinType, KotlinClass ko
253284
// Sometimes Kotlin keeps its native types rather than converting them to Java native types
254285
// ie: "Lkotlin/UShort;" instead of "S"
255286
if(javaType.BinaryName.StartsWith("L",StringComparison.Ordinal)&&javaType.BinaryName.EndsWith(";",StringComparison.Ordinal)){
256-
if(KotlinUtilities.ConvertKotlinClassToJava(javaType.BinaryName.Substring(1,javaType.BinaryName.Length-2))==KotlinUtilities.ConvertKotlinTypeSignature(kotlinType,kotlinClass))
287+
if(KotlinUtilities.ConvertKotlinClassToJava(javaType.BinaryName.Substring(1,javaType.BinaryName.Length-2))==KotlinUtilities.ConvertKotlinTypeSignature(kotlinType,kotlinFile))
257288
returntrue;
258289
}
259290

260291
// Same for some arrays
261292
if(javaType.BinaryName.StartsWith("[L",StringComparison.Ordinal)&&javaType.BinaryName.EndsWith(";",StringComparison.Ordinal)){
262-
if("["+KotlinUtilities.ConvertKotlinClassToJava(javaType.BinaryName.Substring(2,javaType.BinaryName.Length-3))==KotlinUtilities.ConvertKotlinTypeSignature(kotlinType,kotlinClass))
293+
if("["+KotlinUtilities.ConvertKotlinClassToJava(javaType.BinaryName.Substring(2,javaType.BinaryName.Length-3))==KotlinUtilities.ConvertKotlinTypeSignature(kotlinType,kotlinFile))
263294
returntrue;
264295
}
265296

266297
returnfalse;
267298
}
299+
300+
staticstringGetKotlinType(stringjvmType,stringkotlinClass)
301+
{
302+
// Handle erasure of Kotlin unsigned types
303+
if(jvmType=="I"&&kotlinClass=="kotlin/UInt;")
304+
return"uint";
305+
if(jvmType=="[I"&&kotlinClass=="kotlin/UIntArray;")
306+
return"uint[]";
307+
if(jvmType=="S"&&kotlinClass=="kotlin/UShort;")
308+
return"ushort";
309+
if(jvmType=="[S"&&kotlinClass=="kotlin/UShortArray;")
310+
return"ushort[]";
311+
if(jvmType=="J"&&kotlinClass=="kotlin/ULong;")
312+
return"ulong";
313+
if(jvmType=="[J"&&kotlinClass=="kotlin/ULongArray;")
314+
return"ulong[]";
315+
if(jvmType=="B"&&kotlinClass=="kotlin/UByte;")
316+
return"ubyte";
317+
if(jvmType=="[B"&&kotlinClass=="kotlin/UByteArray;")
318+
return"ubyte[]";
319+
320+
returnnull;
321+
}
268322
}
269323
}

‎src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinUtilities.cs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ namespace Xamarin.Android.Tools.Bytecode
88
{
99
publicstaticclassKotlinUtilities
1010
{
11-
publicstaticstringConvertKotlinTypeSignature(KotlinTypetype,KotlinClassklass=null)
11+
publicstaticstringConvertKotlinTypeSignature(KotlinTypetype,KotlinFilemetadata=null)
1212
{
1313
if(typeisnull)
1414
returnstring.Empty;
1515

1616
varclass_name=type.ClassName;
1717

1818
if(string.IsNullOrWhiteSpace(class_name)){
19-
if(klassisobject){
19+
if(metadataisKotlinClassklass){
2020

2121
vartp=klass.TypeParameters.FirstOrDefault(t =>t.Id==type.TypeParameter);
2222

‎src/Xamarin.Android.Tools.Bytecode/Methods.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public sealed class MethodInfo {
3131
publicClassFileDeclaringType{get;privateset;}
3232
publicMethodAccessFlagsAccessFlags{get;set;}
3333
publicAttributeCollectionAttributes{get;privateset;}
34+
publicstringKotlinReturnType{get;set;}
3435

3536
publicMethodInfo(ConstantPoolconstantPool,ClassFiledeclaringType,Streamstream)
3637
{
@@ -290,6 +291,7 @@ public sealed class ParameterInfo : IEquatable<ParameterInfo> {
290291
publicstringName;
291292
publicintPosition;
292293
publicTypeInfoType=newTypeInfo();
294+
publicstringKotlinType;
293295

294296
publicMethodParameterAccessFlagsAccessFlags;
295297

‎src/Xamarin.Android.Tools.Bytecode/Xamarin.Android.Tools.Bytecode.csproj‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</PropertyGroup>
1414

1515
<ItemGroup>
16-
<PackageReferenceInclude="protobuf-net"Version="2.4.1" />
16+
<PackageReferenceInclude="protobuf-net"Version="2.4.4" />
1717
</ItemGroup>
1818

1919
</Project>

0 commit comments

Comments
 (0)