diff --git a/src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinUtilities.cs b/src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinUtilities.cs index bf68a8c8e..e27b04c09 100644 --- a/src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinUtilities.cs +++ b/src/Xamarin.Android.Tools.Bytecode/Kotlin/KotlinUtilities.cs @@ -97,8 +97,7 @@ public static string GetMethodNameWithoutUnsignedSuffix (string name) public static bool IsDefaultConstructorMarker (this MethodInfo method) { - // A default constructor is synthetic and always has an int and a - // DefaultConstructorMarker as its final 2 parameters. + // A default constructor is synthetic and has a DefaultConstructorMarker as its final parameter. if (method.Name != "") return false; @@ -107,12 +106,11 @@ public static bool IsDefaultConstructorMarker (this MethodInfo method) var parameters = method.GetParameters (); - if (parameters.Length < 2) + if (parameters.Length < 1) return false; - // Parameter list ends with `int, DefaultConstructorMarker`. - return parameters [parameters.Length - 2].Type.TypeSignature == "I" && - parameters [parameters.Length - 1].Type.TypeSignature == "Lkotlin/jvm/internal/DefaultConstructorMarker;"; + // Parameter list ends with `DefaultConstructorMarker`. + return parameters [parameters.Length - 1].Type.TypeSignature == "Lkotlin/jvm/internal/DefaultConstructorMarker;"; } // Sometimes the Kotlin provided JvmSignature is null (or unhelpful), so we need to construct one ourselves diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/KotlinFixupsTests.cs b/tests/Xamarin.Android.Tools.Bytecode-Tests/KotlinFixupsTests.cs index 292ea5f2a..e92deeb95 100644 --- a/tests/Xamarin.Android.Tools.Bytecode-Tests/KotlinFixupsTests.cs +++ b/tests/Xamarin.Android.Tools.Bytecode-Tests/KotlinFixupsTests.cs @@ -92,6 +92,28 @@ public void HideDefaultConstructorMarker () Assert.False (ctor_3p.AccessFlags.HasFlag (MethodAccessFlags.Public)); } + [Test] + public void HidePrivateDefaultConstructorMarker () + { + var klass = LoadClassFile ("PrivateDefaultConstructor.class"); + + // init (int isFoo) + var ctor_1p = klass.Methods.Single (m => m.Name == "" && m.GetParameters ().Length == 1); + + // init (int isFoo, DefaultConstructorMarker p1) + var ctor_2p = klass.Methods.Single (m => m.Name == "" && m.GetParameters ().Length == 2); + + Assert.True (ctor_2p.AccessFlags.HasFlag (MethodAccessFlags.Public)); + + KotlinFixups.Fixup ([klass]); + + // Assert that the normal constructor is still public + Assert.False (ctor_1p.AccessFlags.HasFlag (MethodAccessFlags.Public)); + + // Assert that the synthetic "DefaultConstructorMarker" constructor has been marked private + Assert.False (ctor_2p.AccessFlags.HasFlag (MethodAccessFlags.Public)); + } + [Test] public void HideImplementationMethod () { diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor$Default.class b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor$Default.class new file mode 100644 index 000000000..26045198c Binary files /dev/null and b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor$Default.class differ diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor.class b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor.class new file mode 100644 index 000000000..a1588dfc6 Binary files /dev/null and b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor.class differ diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor.kt b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor.kt new file mode 100644 index 000000000..15c0719cd --- /dev/null +++ b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/PrivateDefaultConstructor.kt @@ -0,0 +1,5 @@ +public open class PrivateDefaultConstructor private constructor (internal val isFoo: Boolean) { + init { } + + public companion object Default : PrivateDefaultConstructor (isFoo = false) { } +}