File tree Expand file tree Collapse file tree 7 files changed +59
-38
lines changed
src/Xamarin.Android.Tools.Bytecode/Kotlin
tests/Xamarin.Android.Tools.Bytecode-Tests Expand file tree Collapse file tree 7 files changed +59
-38
lines changed Original file line number Diff line number Diff line change @@ -93,6 +93,12 @@ static void FixupJavaMethods (Methods methods)
9393 method . AccessFlags = MethodAccessFlags . Private ;
9494 }
9595
96+ // Hide constructor if it's the synthetic DefaultConstructorMarker one
97+ foreach ( var method in methods . Where ( method => method . IsDefaultConstructorMarker ( ) ) ) {
98+ Log . Debug ( $ "Kotlin: Hiding synthetic default constructor in class '{ method . DeclaringType ? . ThisClass . Name . Value } ' with signature '{ method . Descriptor } '") ;
99+ method . AccessFlags = ( ( method . AccessFlags ^ MethodAccessFlags . Public ) & method . AccessFlags ) | MethodAccessFlags . Private ;
100+ }
101+
96102 // Better parameter names in extension methods
97103 foreach ( var method in methods . Where ( m => m . IsPubliclyVisible && m . AccessFlags . HasFlag ( MethodAccessFlags . Static ) ) )
98104 FixupExtensionMethod ( method ) ;
Original file line number Diff line number Diff line change @@ -72,6 +72,29 @@ public static string GetMethodNameWithoutSuffix (this MethodInfo method)
7272 return index >= 0 ? method . Name . Substring ( 0 , index ) : method . Name ;
7373 }
7474
75+ public static bool IsDefaultConstructorMarker ( this MethodInfo method )
76+ {
77+ // A default constructor is synthetic and always has an int and a
78+ // DefaultConstructorMarker as its final 2 parameters.
79+ if ( method . Name != "<init>" )
80+ return false ;
81+
82+ if ( ! method . AccessFlags . HasFlag ( MethodAccessFlags . Synthetic ) )
83+ return false ;
84+
85+ var parameters = method . GetParameters ( ) ;
86+
87+ if ( parameters . Length < 2 )
88+ return false ;
89+
90+ // Final parameter is DefaultConstructorMarker
91+ if ( parameters . Last ( ) . Type . TypeSignature != "Lkotlin/jvm/internal/DefaultConstructorMarker;" )
92+ return false ;
93+
94+ // Next to final parameter is int
95+ return parameters [ parameters . Length - 2 ] . Type . TypeSignature == "I" ;
96+ }
97+
7598 public static bool IsPubliclyVisible ( this ClassAccessFlags flags ) => flags . HasFlag ( ClassAccessFlags . Public ) || flags . HasFlag ( ClassAccessFlags . Protected ) ;
7699
77100 public static bool IsPubliclyVisible ( this KotlinClassVisibility flags ) => flags == KotlinClassVisibility . Public || flags == KotlinClassVisibility . Protected ;
Original file line number Diff line number Diff line change @@ -51,6 +51,32 @@ public void HideInternalConstructor ()
5151 Assert . False ( ctor . AccessFlags . HasFlag ( MethodAccessFlags . Public ) ) ;
5252 }
5353
54+ [ Test ]
55+ public void HideDefaultConstructorMarker ( )
56+ {
57+ var klass = LoadClassFile ( "DefaultConstructor.class" ) ;
58+
59+ // init ()
60+ var ctor_0p = klass . Methods . Single ( m => m . Name == "<init>" && m . GetParameters ( ) . Length == 0 ) ;
61+
62+ // init (string name)
63+ var ctor_1p = klass . Methods . Single ( m => m . Name == "<init>" && m . GetParameters ( ) . Length == 1 ) ;
64+
65+ // init (string p0, int p1, DefaultConstructorMarker p2)
66+ var ctor_3p = klass . Methods . Single ( m => m . Name == "<init>" && m . GetParameters ( ) . Length == 3 ) ;
67+
68+ Assert . True ( ctor_3p . AccessFlags . HasFlag ( MethodAccessFlags . Public ) ) ;
69+
70+ KotlinFixups . Fixup ( new [ ] { klass } ) ;
71+
72+ // Assert that the normal constructors are still public
73+ Assert . True ( ctor_0p . AccessFlags . HasFlag ( MethodAccessFlags . Public ) ) ;
74+ Assert . True ( ctor_1p . AccessFlags . HasFlag ( MethodAccessFlags . Public ) ) ;
75+
76+ // Assert that the synthetic "DefaultConstructorMarker" constructor has been marked private
77+ Assert . False ( ctor_3p . AccessFlags . HasFlag ( MethodAccessFlags . Public ) ) ;
78+ }
79+
5480 [ Test ]
5581 public void HideImplementationMethod ( )
5682 {
Original file line number Diff line number Diff line change 7575 type =" boolean"
7676 jni-type =" Z" />
7777 </constructor >
78- <constructor
79- deprecated =" not deprecated"
80- final =" false"
81- name =" JvmOverloadsConstructor"
82- static =" false"
83- visibility =" public"
84- bridge =" false"
85- synthetic =" true"
86- jni-signature =" (LJvmOverloadsConstructor;IILjava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V" >
87- <parameter
88- name =" p0"
89- type =" JvmOverloadsConstructor"
90- jni-type =" LJvmOverloadsConstructor;" />
91- <parameter
92- name =" p1"
93- type =" int"
94- jni-type =" I" />
95- <parameter
96- name =" p2"
97- type =" int"
98- jni-type =" I" />
99- <parameter
100- name =" p3"
101- type =" java.lang.String"
102- jni-type =" Ljava/lang/String;" />
103- <parameter
104- name =" p4"
105- type =" boolean"
106- jni-type =" Z" />
107- <parameter
108- name =" p5"
109- type =" int"
110- jni-type =" I" />
111- <parameter
112- name =" p6"
113- type =" kotlin.jvm.internal.DefaultConstructorMarker"
114- jni-type =" Lkotlin/jvm/internal/DefaultConstructorMarker;" />
115- </constructor >
11678 <constructor
11779 deprecated =" not deprecated"
11880 final =" false"
Original file line number Diff line number Diff line change 1+ class DefaultConstructor (name : String = " bob" ) {
2+ }
Original file line number Diff line number Diff line change 99 "src\\Java.Interop.Tools.Diagnostics\\Java.Interop.Tools.Diagnostics.csproj",
1010 "src\\Xamarin.Android.Tools.AnnotationSupport\\Xamarin.Android.Tools.AnnotationSupport.csproj",
1111 "src\\Xamarin.Android.Tools.ApiXmlAdjuster\\Xamarin.Android.Tools.ApiXmlAdjuster.csproj",
12+ "src\\Xamarin.Android.Tools.Bytecode\\Xamarin.Android.Tools.Bytecode.csproj",
1213 "src\\Xamarin.SourceWriter\\Xamarin.SourceWriter.csproj",
1314 "tests\\generator-Tests\\generator-Tests.csproj",
15+ "tests\\Xamarin.Android.Tools.Bytecode-Tests\\Xamarin.Android.Tools.Bytecode-Tests.csproj",
1416 "tests\\Xamarin.SourceWriter-Tests\\Xamarin.SourceWriter-Tests.csproj",
1517 "tools\\generator\\generator.csproj",
1618 ]
You can’t perform that action at this time.
0 commit comments