Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[generator] do not emit static properties as instance. #159

Conversation

atsushieno
Copy link
Contributor

Without this, abstract classes that implement java.time.chrono.Chronology
fail to bind because they will try to implement those static properties
as instance (this check had been done for methods, but not for properties).

Without this, abstract classes that implement java.time.chrono.Chronology
fail to bind because they will try to implement those static properties
as instance (this check had been done for methods, but not for properties).
@jonpryor
Copy link
Member

Tests? :-D

@atsushieno
Copy link
Contributor Author

Tests are implemented as Mono.Android API api-diff; if things don't work as expected, changes to Mono.Android.dll build within xamarin-android will not build at all. If it works as expected, it will build.

Since xamarin-android is in separate repository, it is impossible to bring that test as part of this repository.

atsushieno added a commit to atsushieno/xamarin-android that referenced this pull request Jun 16, 2017
... that depended on generator fixes.

The corresponding generator fixes are:

dotnet/java-interop#153
dotnet/java-interop#159

With those changes, this can be brought back to the public API.
@jonpryor
Copy link
Member

That doesn't mean we can't have a minimal test case. The problem, as I understand it, is if we bind:

public interface Fooable {
    public static int getFooableCount() {
        return 42;
    }
}

then our C# binding will incorrectly be:

public interface IFooable {
    public int FooableCount {get;}
}

If so, this can be easily tested by updating tools/generator/Tests/expected/TestInterface/TestInterface.xml so that TestInterface contains a static get method:

<method abstract="false" deprecated="not deprecated" final="true" name="getFooableCount" native="false" return="int" static="true" synchronized="false" visibility="public">
</method>

@atsushieno
Copy link
Contributor Author

It is not as easy as keeping producivity.

@jonpryor
Copy link
Member

It is not as easy as keeping producivity.

I believe that this is false equivalence, trading one "kind" of productivity for another.

Case in point: this PR is buggy. Given the change suggested earlier:

diff --git a/tools/generator/Tests/expected/TestInterface/TestInterface.xml b/tools/generator/Tests/expected/TestInterface/TestInterface.xml
index b490566..2f33295 100644
--- a/tools/generator/Tests/expected/TestInterface/TestInterface.xml
+++ b/tools/generator/Tests/expected/TestInterface/TestInterface.xml
@@ -21,6 +21,8 @@
 			}
 		-->
 		<interface abstract="true" deprecated="not deprecated" final="false" name="TestInterface" static="false" visibility="public">
+			<method abstract="false" deprecated="not deprecated" final="true" name="getFooableCount" native="false" return="int" static="true" synchronized="false" visibility="public">
+			</method>
 			<method abstract="false" deprecated="not deprecated" final="false" name="defaultInterfaceMethod" native="false" return="void" static="false" synchronized="false" visibility="public">
 			</method>
 			<method abstract="true" deprecated="not deprecated" final="false" name="getSpanFlags" native="false" return="int" static="false" synchronized="false" visibility="public">

The result of running:

$ xbuild tools/generator/Tests/generator-Tests.csproj
$ make run-tests TESTS=bin/TestDebug/generator-Tests.dll

is that there are no failures.

Whereas there should be failures. Specifically, there should be a new TestInterface.FooableCount property! But there isn't.

Were we to accept this PR as-is and bump xamarin-android, the result would be that we could now bind java.time.chrono.Chronology (yay), but it would be incomplete, and would not bind the Chronology.getAvailableChronologies() method in any way.

I don't consider this a "good" state of affairs, and adding the two line test to this PR would have caught that, as opposed to a probable alternative process of "accept the PR, merge to x-a, build, wait some time, have someone file a bug report that here is no Chronology.AvailableChronologies property, and then fix the oversight in generator."

Which process, again, is more productive?

atsushieno added a commit to atsushieno/xamarin-android that referenced this pull request Jul 13, 2017
It does not mean everything in this change is about enumification - actually
only few changes are relevant.
It is wrong attitute because it mixes different fixes, but that's what I
was asked to do.

Here is the list of the reported breaking changes:

   Perceptible = <span class='removed removed-inline removed-breaking-inline'>130</span> <span class='added '>230</span>

Google changed the value!

    public RemoteInput.Builder SetAllowFreeFormInput (bool <span class='removed removed-inline removed-breaking-inline'>allowFreeFormInput</span> <span class='added '>allowFreeFormTextInput</span>)

The bare parameter name changes that we already resolved as "renaming to the new name is the way what we do". api-diff most likely needs fix to not report this kind of changes.

	<span class='removed removed-method breaking' data-is-breaking>public virtual void OnServiceAdded (ProfileState status, BluetoothGattService service);</span>

It is actually a bugfix: https://bugzilla.xamarin.com/show_bug.cgi?id=55473

	public <span class='removed removed-inline removed-breaking-inline'>AdvertiseTx</span> <span class='added '>int</span> TxPowerLevel { get; }

It is also a bugfix for https://bugzilla.xamarin.com/show_bug.cgi?id=51293

	public virtual Android.Database.ICursor Query (Android.Net.Uri <span class='removed removed-inline removed-breaking-inline'>url</span> <span class='added '>uri</span>, string[] projection, string selection, string[] selectionArgs, string sortOrder, Android.OS.CancellationSignal cancellationSignal)
	public virtual void OnError (string <span class='removed removed-inline removed-breaking-inline'>itemId</span> <span class='added '>mediaId</span>)
	public virtual bool EnableNetwork (int netId, bool <span class='removed removed-inline removed-breaking-inline'>disableOthers</span> <span class='added '>attemptConnect</span>)
	public virtual SubscriptionInfo GetActiveSubscriptionInfoForSimSlotIndex (int <span class='removed removed-inline removed-breaking-inline'>slotIdx</span> <span class='added '>slotIndex</span>)
	public virtual string GetDeviceId (int <span class='removed removed-inline removed-breaking-inline'>slotId</span> <span class='added '>slotIndex</span>)
	public virtual void SetMaxEms (int <span class='removed removed-inline removed-breaking-inline'>maxems</span> <span class='added '>maxEms</span>)
	public virtual void SetMaxHeight (int <span class='removed removed-inline removed-breaking-inline'>maxHeight</span> <span class='added '>maxPixels</span>)
	(... and all those relevant methods on Android.Widget.TextView)
	public bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public bool IsAssignableFrom (Class <span class='removed removed-inline removed-breaking-inline'>c</span> <span class='added '>cls</span>)
	public bool IsInstance (Object <span class='removed removed-inline removed-breaking-inline'>object</span> <span class='added '>obj</span>)
	public virtual bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public virtual void TraceInstructions (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual void TraceMethodCalls (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual bool IsAnnotationPresent (Java.Lang.Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public Java.Lang.Object NewInstance (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>args</span> <span class='added '>initargs</span>)
	public string GetDisplayScript (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public string GetDisplayVariant (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public virtual int NextInt (int <span class='removed removed-inline removed-breaking-inline'>n</span> <span class='added '>bound</span>)
	public CopyOnWriteArrayList (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>array</span> <span class='added '>toCopyIn</span>)
	(... and all those lines in Java.Util.Concurrent.CopyOnWriteArrayList)

They are all parameter name fixes in Android API.

	MaskFlags = <span class='removed removed-inline removed-breaking-inline'>4080</span> <span class='added '>65520</span>

Google changed the constant value here too. Well, it should.

	<span class='added added-interface breaking' data-is-breaking>Java.Lang.IAutoCloseable</span>

This is a bogus report. It sure adds another interface but it does not bring in any breaking change because the derived interface XmlResourceParser also contains the only member in AutoCloseable i.e. close() !

api-check must not report this as a breaking change. This applies to all other interfaces that report the same error too.

	<span class='added added-method breaking' data-is-breaking>public virtual View KeyboardNavigationClusterSearch (View p0, FocusSearchDirection p1);</span>

Why is this happening? Because they are static methods that should not be part of the interface member.

Why does this happen? Because this fix is not merged! dotnet/java-interop#159

That fix really needs to be merged otherwise we keep generating these API incomatibility forever. The issue on java.time.chrono API mentioned there is actually due to totally different issue from the static <-> instance changes, so there is no excuse to not fix the static issue.

	<span class='removed removed-method breaking' data-is-breaking>public IAppendable Append (string s, int start, int end);</span>

Fixed: see src/Mono.Android/Java.Lang/StringBuffer.cs and src/Mono.Android/Java.Lang/StringBuilder.cs for details.

	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Constructor.InterfaceConsts</span></h3>
	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Method.InterfaceConsts</span></h3>

They must be brought be intrusive Google API changes due to the step-by-step migration from Harmony to OpenJDK. There are no members that used those consts and should be simply killed even without changes. We can take bugs IF ANYONE EVER used it. I don't waste my time on "fixing" this.

	<span class='removed removed-method breaking' data-is-breaking>public virtual bool IsAnnotationPresent (Java.Lang.Class annotationClass);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void AddPropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void RemovePropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	(in both Pack200.IPacker and Pack200.IUnpacker)
	<span class='removed removed-property breaking' data-is-breaking>public virtual bool IsDestroyed { get; }</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void Destroy ();</span>

They are all api-merge bug: why does api-merge preserve this method as a default interface method?? It had been non-default in earlier API Levels, therefore api-merge must generate this method as non-default.

	<span class='added added-interface breaking' data-is-breaking>IAnnotatedElement</span>

This is new in java.lang.reflect.GenericDeclaration interface and should also be part of huge Harmony - OpenJDK migration. And unlike other new additional interfaces, those methods in AnnotatedElement are not default, so they are indeed breaking changes.

At this state, I don't think there is anything we can help the situation. We cannot remove this base interface type because that will generate JCW  that doesn't compile.

The only idea I can think of is to completely kill this type. It's just like we give up EntityIterator.

	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Position (long newPosition);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Truncate (long size);</span>
	<span class='removed removed-method breaking' data-is-breaking>public System.Threading.Tasks.Task&lt;FileChannel&gt; TruncateAsync (long size);</span>

This was actually newly introduced breakage for OpenJDK migration too. FileChannel now implements SeekableByteChannel, which never existed, and they require those methods to return ISeekableByteChannel in C#, not FileChannel whereas FileChannel **is** ISeekableByteChannel.

So they are changed in the metadata fixup, but then this breakage. Now Position() and Truncate() are added as explicit interface implementation.

However, what can we do for TruncateAsync() ? NOTHING! It is (semi-)automatically generated by `generateAsyncWrapper='true'` which is NOT defined in the interface and therefore it cannot be explicitly implemented. And it's all about return types.

	<span class='added added-interface breaking' data-is-breaking>Javax.Security.Auth.IDestroyable</span>

This should not be reported because all those interface methods are default!

	<h3>Removed Type <span class='breaking' data-is-breaking>Android.Service.Quicksettings.TileState</span></h3></div> <!-- end namespace Android.Service.Quicksettings -->

I explicitly removed this. It had been marked as [Obsolete].
atsushieno added a commit to atsushieno/xamarin-android that referenced this pull request Jul 13, 2017
It does not mean everything in this change is about enumification - actually
only few changes are relevant.
It is wrong attitute because it mixes different fixes, but that's what I
was asked to do.

Here is the list of the reported breaking changes:

   Perceptible = <span class='removed removed-inline removed-breaking-inline'>130</span> <span class='added '>230</span>

Google changed the value!

    public RemoteInput.Builder SetAllowFreeFormInput (bool <span class='removed removed-inline removed-breaking-inline'>allowFreeFormInput</span> <span class='added '>allowFreeFormTextInput</span>)

The bare parameter name changes that we already resolved as "renaming to the new name is the way what we do". api-diff most likely needs fix to not report this kind of changes.

	<span class='removed removed-method breaking' data-is-breaking>public virtual void OnServiceAdded (ProfileState status, BluetoothGattService service);</span>

It is actually a bugfix: https://bugzilla.xamarin.com/show_bug.cgi?id=55473

	public <span class='removed removed-inline removed-breaking-inline'>AdvertiseTx</span> <span class='added '>int</span> TxPowerLevel { get; }

It is also a bugfix for https://bugzilla.xamarin.com/show_bug.cgi?id=51293

	public virtual Android.Database.ICursor Query (Android.Net.Uri <span class='removed removed-inline removed-breaking-inline'>url</span> <span class='added '>uri</span>, string[] projection, string selection, string[] selectionArgs, string sortOrder, Android.OS.CancellationSignal cancellationSignal)
	public virtual void OnError (string <span class='removed removed-inline removed-breaking-inline'>itemId</span> <span class='added '>mediaId</span>)
	public virtual bool EnableNetwork (int netId, bool <span class='removed removed-inline removed-breaking-inline'>disableOthers</span> <span class='added '>attemptConnect</span>)
	public virtual SubscriptionInfo GetActiveSubscriptionInfoForSimSlotIndex (int <span class='removed removed-inline removed-breaking-inline'>slotIdx</span> <span class='added '>slotIndex</span>)
	public virtual string GetDeviceId (int <span class='removed removed-inline removed-breaking-inline'>slotId</span> <span class='added '>slotIndex</span>)
	public virtual void SetMaxEms (int <span class='removed removed-inline removed-breaking-inline'>maxems</span> <span class='added '>maxEms</span>)
	public virtual void SetMaxHeight (int <span class='removed removed-inline removed-breaking-inline'>maxHeight</span> <span class='added '>maxPixels</span>)
	(... and all those relevant methods on Android.Widget.TextView)
	public bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public bool IsAssignableFrom (Class <span class='removed removed-inline removed-breaking-inline'>c</span> <span class='added '>cls</span>)
	public bool IsInstance (Object <span class='removed removed-inline removed-breaking-inline'>object</span> <span class='added '>obj</span>)
	public virtual bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public virtual void TraceInstructions (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual void TraceMethodCalls (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual bool IsAnnotationPresent (Java.Lang.Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public Java.Lang.Object NewInstance (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>args</span> <span class='added '>initargs</span>)
	public string GetDisplayScript (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public string GetDisplayVariant (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public virtual int NextInt (int <span class='removed removed-inline removed-breaking-inline'>n</span> <span class='added '>bound</span>)
	public CopyOnWriteArrayList (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>array</span> <span class='added '>toCopyIn</span>)
	(... and all those lines in Java.Util.Concurrent.CopyOnWriteArrayList)

They are all parameter name fixes in Android API.

	MaskFlags = <span class='removed removed-inline removed-breaking-inline'>4080</span> <span class='added '>65520</span>

Google changed the constant value here too. Well, it should.

	<span class='added added-interface breaking' data-is-breaking>Java.Lang.IAutoCloseable</span>

This is a bogus report. It sure adds another interface but it does not bring in any breaking change because the derived interface XmlResourceParser also contains the only member in AutoCloseable i.e. close() !

api-check must not report this as a breaking change. This applies to all other interfaces that report the same error too.

	<span class='added added-method breaking' data-is-breaking>public virtual View KeyboardNavigationClusterSearch (View p0, FocusSearchDirection p1);</span>

Why is this happening? Because they are static methods that should not be part of the interface member.

Why does this happen? Because this fix is not merged! dotnet/java-interop#159

That fix really needs to be merged otherwise we keep generating these API incomatibility forever. The issue on java.time.chrono API mentioned there is actually due to totally different issue from the static <-> instance changes, so there is no excuse to not fix the static issue.

	<span class='removed removed-method breaking' data-is-breaking>public IAppendable Append (string s, int start, int end);</span>

Fixed: see src/Mono.Android/Java.Lang/StringBuffer.cs and src/Mono.Android/Java.Lang/StringBuilder.cs for details.

	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Constructor.InterfaceConsts</span></h3>
	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Method.InterfaceConsts</span></h3>

They must be brought be intrusive Google API changes due to the step-by-step migration from Harmony to OpenJDK. There are no members that used those consts and should be simply killed even without changes. We can take bugs IF ANYONE EVER used it. I don't waste my time on "fixing" this.

	<span class='removed removed-method breaking' data-is-breaking>public virtual bool IsAnnotationPresent (Java.Lang.Class annotationClass);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void AddPropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void RemovePropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	(in both Pack200.IPacker and Pack200.IUnpacker)
	<span class='removed removed-property breaking' data-is-breaking>public virtual bool IsDestroyed { get; }</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void Destroy ();</span>

They are all api-merge bug: why does api-merge preserve this method as a default interface method?? It had been non-default in earlier API Levels, therefore api-merge must generate this method as non-default.

	<span class='added added-interface breaking' data-is-breaking>IAnnotatedElement</span>

This is new in java.lang.reflect.GenericDeclaration interface and should also be part of huge Harmony - OpenJDK migration. And unlike other new additional interfaces, those methods in AnnotatedElement are not default, so they are indeed breaking changes.

At this state, I don't think there is anything we can help the situation. We cannot remove this base interface type because that will generate JCW  that doesn't compile.

The only idea I can think of is to completely kill this type. It's just like we give up EntityIterator.

	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Position (long newPosition);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Truncate (long size);</span>
	<span class='removed removed-method breaking' data-is-breaking>public System.Threading.Tasks.Task&lt;FileChannel&gt; TruncateAsync (long size);</span>

This was actually newly introduced breakage for OpenJDK migration too. FileChannel now implements SeekableByteChannel, which never existed, and they require those methods to return ISeekableByteChannel in C#, not FileChannel whereas FileChannel **is** ISeekableByteChannel.

So they are changed in the metadata fixup, but then this breakage. Now Position() and Truncate() are added as explicit interface implementation.

However, what can we do for TruncateAsync() ? NOTHING! It is (semi-)automatically generated by `generateAsyncWrapper='true'` which is NOT defined in the interface and therefore it cannot be explicitly implemented. And it's all about return types.

	<span class='added added-interface breaking' data-is-breaking>Javax.Security.Auth.IDestroyable</span>

This should not be reported because all those interface methods are default!

	<h3>Removed Type <span class='breaking' data-is-breaking>Android.Service.Quicksettings.TileState</span></h3></div> <!-- end namespace Android.Service.Quicksettings -->

I explicitly removed this. It had been marked as [Obsolete].
atsushieno added a commit to atsushieno/xamarin-android that referenced this pull request Jul 13, 2017
It does not mean everything in this change is about enumification - actually
only few changes are relevant.
It is wrong attitute because it mixes different fixes, but that's what I
was asked to do.

Here is the list of the reported breaking changes:

   Perceptible = <span class='removed removed-inline removed-breaking-inline'>130</span> <span class='added '>230</span>

Google changed the value!

    public RemoteInput.Builder SetAllowFreeFormInput (bool <span class='removed removed-inline removed-breaking-inline'>allowFreeFormInput</span> <span class='added '>allowFreeFormTextInput</span>)

The bare parameter name changes that we already resolved as "renaming to the new name is the way what we do". api-diff most likely needs fix to not report this kind of changes.

	<span class='removed removed-method breaking' data-is-breaking>public virtual void OnServiceAdded (ProfileState status, BluetoothGattService service);</span>

It is actually a bugfix: https://bugzilla.xamarin.com/show_bug.cgi?id=55473

	public <span class='removed removed-inline removed-breaking-inline'>AdvertiseTx</span> <span class='added '>int</span> TxPowerLevel { get; }

It is also a bugfix for https://bugzilla.xamarin.com/show_bug.cgi?id=51293

	public virtual Android.Database.ICursor Query (Android.Net.Uri <span class='removed removed-inline removed-breaking-inline'>url</span> <span class='added '>uri</span>, string[] projection, string selection, string[] selectionArgs, string sortOrder, Android.OS.CancellationSignal cancellationSignal)
	public virtual void OnError (string <span class='removed removed-inline removed-breaking-inline'>itemId</span> <span class='added '>mediaId</span>)
	public virtual bool EnableNetwork (int netId, bool <span class='removed removed-inline removed-breaking-inline'>disableOthers</span> <span class='added '>attemptConnect</span>)
	public virtual SubscriptionInfo GetActiveSubscriptionInfoForSimSlotIndex (int <span class='removed removed-inline removed-breaking-inline'>slotIdx</span> <span class='added '>slotIndex</span>)
	public virtual string GetDeviceId (int <span class='removed removed-inline removed-breaking-inline'>slotId</span> <span class='added '>slotIndex</span>)
	public virtual void SetMaxEms (int <span class='removed removed-inline removed-breaking-inline'>maxems</span> <span class='added '>maxEms</span>)
	public virtual void SetMaxHeight (int <span class='removed removed-inline removed-breaking-inline'>maxHeight</span> <span class='added '>maxPixels</span>)
	(... and all those relevant methods on Android.Widget.TextView)
	public bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public bool IsAssignableFrom (Class <span class='removed removed-inline removed-breaking-inline'>c</span> <span class='added '>cls</span>)
	public bool IsInstance (Object <span class='removed removed-inline removed-breaking-inline'>object</span> <span class='added '>obj</span>)
	public virtual bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public virtual void TraceInstructions (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual void TraceMethodCalls (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual bool IsAnnotationPresent (Java.Lang.Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public Java.Lang.Object NewInstance (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>args</span> <span class='added '>initargs</span>)
	public string GetDisplayScript (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public string GetDisplayVariant (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public virtual int NextInt (int <span class='removed removed-inline removed-breaking-inline'>n</span> <span class='added '>bound</span>)
	public CopyOnWriteArrayList (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>array</span> <span class='added '>toCopyIn</span>)
	(... and all those lines in Java.Util.Concurrent.CopyOnWriteArrayList)

They are all parameter name fixes in Android API.

	MaskFlags = <span class='removed removed-inline removed-breaking-inline'>4080</span> <span class='added '>65520</span>

Google changed the constant value here too. Well, it should.

	<span class='added added-interface breaking' data-is-breaking>Java.Lang.IAutoCloseable</span>

This is a bogus report. It sure adds another interface but it does not bring in any breaking change because the derived interface XmlResourceParser also contains the only member in AutoCloseable i.e. close() !

api-check must not report this as a breaking change. This applies to all other interfaces that report the same error too.

	<span class='added added-method breaking' data-is-breaking>public virtual View KeyboardNavigationClusterSearch (View p0, FocusSearchDirection p1);</span>

Why is this happening? Because they are static methods that should not be part of the interface member.

Why does this happen? Because this fix is not merged! dotnet/java-interop#159

That fix really needs to be merged otherwise we keep generating these API incomatibility forever. The issue on java.time.chrono API mentioned there is actually due to totally different issue from the static <-> instance changes, so there is no excuse to not fix the static issue.

	<span class='removed removed-method breaking' data-is-breaking>public IAppendable Append (string s, int start, int end);</span>

Fixed: see src/Mono.Android/Java.Lang/StringBuffer.cs and src/Mono.Android/Java.Lang/StringBuilder.cs for details.

	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Constructor.InterfaceConsts</span></h3>
	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Method.InterfaceConsts</span></h3>

They must be brought be intrusive Google API changes due to the step-by-step migration from Harmony to OpenJDK. There are no members that used those consts and should be simply killed even without changes. We can take bugs IF ANYONE EVER used it. I don't waste my time on "fixing" this.

	<span class='removed removed-method breaking' data-is-breaking>public virtual bool IsAnnotationPresent (Java.Lang.Class annotationClass);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void AddPropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void RemovePropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	(in both Pack200.IPacker and Pack200.IUnpacker)
	<span class='removed removed-property breaking' data-is-breaking>public virtual bool IsDestroyed { get; }</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void Destroy ();</span>

They are all api-merge bug: why does api-merge preserve this method as a default interface method?? It had been non-default in earlier API Levels, therefore api-merge must generate this method as non-default.

	<span class='added added-interface breaking' data-is-breaking>IAnnotatedElement</span>

This is new in java.lang.reflect.GenericDeclaration interface and should also be part of huge Harmony - OpenJDK migration. And unlike other new additional interfaces, those methods in AnnotatedElement are not default, so they are indeed breaking changes.

At this state, I don't think there is anything we can help the situation. We cannot remove this base interface type because that will generate JCW  that doesn't compile.

The only idea I can think of is to completely kill this type. It's just like we give up EntityIterator.

	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Position (long newPosition);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Truncate (long size);</span>
	<span class='removed removed-method breaking' data-is-breaking>public System.Threading.Tasks.Task&lt;FileChannel&gt; TruncateAsync (long size);</span>

This was actually newly introduced breakage for OpenJDK migration too. FileChannel now implements SeekableByteChannel, which never existed, and they require those methods to return ISeekableByteChannel in C#, not FileChannel whereas FileChannel **is** ISeekableByteChannel.

So they are changed in the metadata fixup, but then this breakage. Now Position() and Truncate() are added as explicit interface implementation.

However, what can we do for TruncateAsync() ? NOTHING! It is (semi-)automatically generated by `generateAsyncWrapper='true'` which is NOT defined in the interface and therefore it cannot be explicitly implemented. And it's all about return types.

	<span class='added added-interface breaking' data-is-breaking>Javax.Security.Auth.IDestroyable</span>

This should not be reported because all those interface methods are default!

	<h3>Removed Type <span class='breaking' data-is-breaking>Android.Service.Quicksettings.TileState</span></h3></div> <!-- end namespace Android.Service.Quicksettings -->

I explicitly removed this. It had been marked as [Obsolete].
atsushieno added a commit to atsushieno/xamarin-android that referenced this pull request Jul 19, 2017
It does not mean everything in this change is about enumification - actually
only few changes are relevant.
It is wrong attitute because it mixes different fixes, but that's what I
was asked to do.

Here is the list of the reported breaking changes:

   Perceptible = <span class='removed removed-inline removed-breaking-inline'>130</span> <span class='added '>230</span>

Google changed the value!

    public RemoteInput.Builder SetAllowFreeFormInput (bool <span class='removed removed-inline removed-breaking-inline'>allowFreeFormInput</span> <span class='added '>allowFreeFormTextInput</span>)

The bare parameter name changes that we already resolved as "renaming to the new name is the way what we do". api-diff most likely needs fix to not report this kind of changes.

	<span class='removed removed-method breaking' data-is-breaking>public virtual void OnServiceAdded (ProfileState status, BluetoothGattService service);</span>

It is actually a bugfix: https://bugzilla.xamarin.com/show_bug.cgi?id=55473

	public <span class='removed removed-inline removed-breaking-inline'>AdvertiseTx</span> <span class='added '>int</span> TxPowerLevel { get; }

It is also a bugfix for https://bugzilla.xamarin.com/show_bug.cgi?id=51293

	public virtual Android.Database.ICursor Query (Android.Net.Uri <span class='removed removed-inline removed-breaking-inline'>url</span> <span class='added '>uri</span>, string[] projection, string selection, string[] selectionArgs, string sortOrder, Android.OS.CancellationSignal cancellationSignal)
	public virtual void OnError (string <span class='removed removed-inline removed-breaking-inline'>itemId</span> <span class='added '>mediaId</span>)
	public virtual bool EnableNetwork (int netId, bool <span class='removed removed-inline removed-breaking-inline'>disableOthers</span> <span class='added '>attemptConnect</span>)
	public virtual SubscriptionInfo GetActiveSubscriptionInfoForSimSlotIndex (int <span class='removed removed-inline removed-breaking-inline'>slotIdx</span> <span class='added '>slotIndex</span>)
	public virtual string GetDeviceId (int <span class='removed removed-inline removed-breaking-inline'>slotId</span> <span class='added '>slotIndex</span>)
	public virtual void SetMaxEms (int <span class='removed removed-inline removed-breaking-inline'>maxems</span> <span class='added '>maxEms</span>)
	public virtual void SetMaxHeight (int <span class='removed removed-inline removed-breaking-inline'>maxHeight</span> <span class='added '>maxPixels</span>)
	(... and all those relevant methods on Android.Widget.TextView)
	public bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public bool IsAssignableFrom (Class <span class='removed removed-inline removed-breaking-inline'>c</span> <span class='added '>cls</span>)
	public bool IsInstance (Object <span class='removed removed-inline removed-breaking-inline'>object</span> <span class='added '>obj</span>)
	public virtual bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public virtual void TraceInstructions (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual void TraceMethodCalls (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual bool IsAnnotationPresent (Java.Lang.Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public Java.Lang.Object NewInstance (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>args</span> <span class='added '>initargs</span>)
	public string GetDisplayScript (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public string GetDisplayVariant (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public virtual int NextInt (int <span class='removed removed-inline removed-breaking-inline'>n</span> <span class='added '>bound</span>)
	public CopyOnWriteArrayList (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>array</span> <span class='added '>toCopyIn</span>)
	(... and all those lines in Java.Util.Concurrent.CopyOnWriteArrayList)

They are all parameter name fixes in Android API.

	MaskFlags = <span class='removed removed-inline removed-breaking-inline'>4080</span> <span class='added '>65520</span>

Google changed the constant value here too. Well, it should.

	<span class='added added-interface breaking' data-is-breaking>Java.Lang.IAutoCloseable</span>

This is a bogus report. It sure adds another interface but it does not bring in any breaking change because the derived interface XmlResourceParser also contains the only member in AutoCloseable i.e. close() !

api-check must not report this as a breaking change. This applies to all other interfaces that report the same error too.

	<span class='added added-method breaking' data-is-breaking>public virtual View KeyboardNavigationClusterSearch (View p0, FocusSearchDirection p1);</span>

Why is this happening? Because they are static methods that should not be part of the interface member.

Why does this happen? Because this fix is not merged! dotnet/java-interop#159

That fix really needs to be merged otherwise we keep generating these API incomatibility forever. The issue on java.time.chrono API mentioned there is actually due to totally different issue from the static <-> instance changes, so there is no excuse to not fix the static issue.

	<span class='removed removed-method breaking' data-is-breaking>public IAppendable Append (string s, int start, int end);</span>

Fixed: see src/Mono.Android/Java.Lang/StringBuffer.cs and src/Mono.Android/Java.Lang/StringBuilder.cs for details.

	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Constructor.InterfaceConsts</span></h3>
	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Method.InterfaceConsts</span></h3>

They must be brought be intrusive Google API changes due to the step-by-step migration from Harmony to OpenJDK. There are no members that used those consts and should be simply killed even without changes. We can take bugs IF ANYONE EVER used it. I don't waste my time on "fixing" this.

	<span class='removed removed-method breaking' data-is-breaking>public virtual bool IsAnnotationPresent (Java.Lang.Class annotationClass);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void AddPropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void RemovePropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	(in both Pack200.IPacker and Pack200.IUnpacker)
	<span class='removed removed-property breaking' data-is-breaking>public virtual bool IsDestroyed { get; }</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void Destroy ();</span>

They are all api-merge bug: why does api-merge preserve this method as a default interface method?? It had been non-default in earlier API Levels, therefore api-merge must generate this method as non-default.

	<span class='added added-interface breaking' data-is-breaking>IAnnotatedElement</span>

This is new in java.lang.reflect.GenericDeclaration interface and should also be part of huge Harmony - OpenJDK migration. And unlike other new additional interfaces, those methods in AnnotatedElement are not default, so they are indeed breaking changes.

At this state, I don't think there is anything we can help the situation. We cannot remove this base interface type because that will generate JCW  that doesn't compile.

The only idea I can think of is to completely kill this type. It's just like we give up EntityIterator.

	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Position (long newPosition);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Truncate (long size);</span>
	<span class='removed removed-method breaking' data-is-breaking>public System.Threading.Tasks.Task&lt;FileChannel&gt; TruncateAsync (long size);</span>

This was actually newly introduced breakage for OpenJDK migration too. FileChannel now implements SeekableByteChannel, which never existed, and they require those methods to return ISeekableByteChannel in C#, not FileChannel whereas FileChannel **is** ISeekableByteChannel.

So they are changed in the metadata fixup, but then this breakage. Now Position() and Truncate() are added as explicit interface implementation.

However, what can we do for TruncateAsync() ? NOTHING! It is (semi-)automatically generated by `generateAsyncWrapper='true'` which is NOT defined in the interface and therefore it cannot be explicitly implemented. And it's all about return types.

	<span class='added added-interface breaking' data-is-breaking>Javax.Security.Auth.IDestroyable</span>

This should not be reported because all those interface methods are default!

	<h3>Removed Type <span class='breaking' data-is-breaking>Android.Service.Quicksettings.TileState</span></h3></div> <!-- end namespace Android.Service.Quicksettings -->

I explicitly removed this. It had been marked as [Obsolete].
atsushieno added a commit to atsushieno/xamarin-android that referenced this pull request Jul 31, 2017
It does not mean everything in this change is about enumification - actually
only few changes are relevant.
It is wrong attitute because it mixes different fixes, but that's what I
was asked to do.

Here is the list of the reported breaking changes:

   Perceptible = <span class='removed removed-inline removed-breaking-inline'>130</span> <span class='added '>230</span>

Google changed the value!

    public RemoteInput.Builder SetAllowFreeFormInput (bool <span class='removed removed-inline removed-breaking-inline'>allowFreeFormInput</span> <span class='added '>allowFreeFormTextInput</span>)

The bare parameter name changes that we already resolved as "renaming to the new name is the way what we do". api-diff most likely needs fix to not report this kind of changes.

	<span class='removed removed-method breaking' data-is-breaking>public virtual void OnServiceAdded (ProfileState status, BluetoothGattService service);</span>

It is actually a bugfix: https://bugzilla.xamarin.com/show_bug.cgi?id=55473

	public <span class='removed removed-inline removed-breaking-inline'>AdvertiseTx</span> <span class='added '>int</span> TxPowerLevel { get; }

It is also a bugfix for https://bugzilla.xamarin.com/show_bug.cgi?id=51293

	public virtual Android.Database.ICursor Query (Android.Net.Uri <span class='removed removed-inline removed-breaking-inline'>url</span> <span class='added '>uri</span>, string[] projection, string selection, string[] selectionArgs, string sortOrder, Android.OS.CancellationSignal cancellationSignal)
	public virtual void OnError (string <span class='removed removed-inline removed-breaking-inline'>itemId</span> <span class='added '>mediaId</span>)
	public virtual bool EnableNetwork (int netId, bool <span class='removed removed-inline removed-breaking-inline'>disableOthers</span> <span class='added '>attemptConnect</span>)
	public virtual SubscriptionInfo GetActiveSubscriptionInfoForSimSlotIndex (int <span class='removed removed-inline removed-breaking-inline'>slotIdx</span> <span class='added '>slotIndex</span>)
	public virtual string GetDeviceId (int <span class='removed removed-inline removed-breaking-inline'>slotId</span> <span class='added '>slotIndex</span>)
	public virtual void SetMaxEms (int <span class='removed removed-inline removed-breaking-inline'>maxems</span> <span class='added '>maxEms</span>)
	public virtual void SetMaxHeight (int <span class='removed removed-inline removed-breaking-inline'>maxHeight</span> <span class='added '>maxPixels</span>)
	(... and all those relevant methods on Android.Widget.TextView)
	public bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public bool IsAssignableFrom (Class <span class='removed removed-inline removed-breaking-inline'>c</span> <span class='added '>cls</span>)
	public bool IsInstance (Object <span class='removed removed-inline removed-breaking-inline'>object</span> <span class='added '>obj</span>)
	public virtual bool IsAnnotationPresent (Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public virtual void TraceInstructions (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual void TraceMethodCalls (bool <span class='removed removed-inline removed-breaking-inline'>enable</span> <span class='added '>on</span>)
	public virtual bool IsAnnotationPresent (Java.Lang.Class <span class='removed removed-inline removed-breaking-inline'>annotationType</span> <span class='added '>annotationClass</span>)
	public Java.Lang.Object NewInstance (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>args</span> <span class='added '>initargs</span>)
	public string GetDisplayScript (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public string GetDisplayVariant (Locale <span class='removed removed-inline removed-breaking-inline'>locale</span> <span class='added '>inLocale</span>)
	public virtual int NextInt (int <span class='removed removed-inline removed-breaking-inline'>n</span> <span class='added '>bound</span>)
	public CopyOnWriteArrayList (Java.Lang.Object[] <span class='removed removed-inline removed-breaking-inline'>array</span> <span class='added '>toCopyIn</span>)
	(... and all those lines in Java.Util.Concurrent.CopyOnWriteArrayList)

They are all parameter name fixes in Android API.

	MaskFlags = <span class='removed removed-inline removed-breaking-inline'>4080</span> <span class='added '>65520</span>

Google changed the constant value here too. Well, it should.

	<span class='added added-interface breaking' data-is-breaking>Java.Lang.IAutoCloseable</span>

This is a bogus report. It sure adds another interface but it does not bring in any breaking change because the derived interface XmlResourceParser also contains the only member in AutoCloseable i.e. close() !

api-check must not report this as a breaking change. This applies to all other interfaces that report the same error too.

	<span class='added added-method breaking' data-is-breaking>public virtual View KeyboardNavigationClusterSearch (View p0, FocusSearchDirection p1);</span>

Why is this happening? Because they are static methods that should not be part of the interface member.

Why does this happen? Because this fix is not merged! dotnet/java-interop#159

That fix really needs to be merged otherwise we keep generating these API incomatibility forever. The issue on java.time.chrono API mentioned there is actually due to totally different issue from the static <-> instance changes, so there is no excuse to not fix the static issue.

	<span class='removed removed-method breaking' data-is-breaking>public IAppendable Append (string s, int start, int end);</span>

Fixed: see src/Mono.Android/Java.Lang/StringBuffer.cs and src/Mono.Android/Java.Lang/StringBuilder.cs for details.

	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Constructor.InterfaceConsts</span></h3>
	<h3>Removed Type <span class='breaking' data-is-breaking>Java.Lang.Reflect.Method.InterfaceConsts</span></h3>

They must be brought be intrusive Google API changes due to the step-by-step migration from Harmony to OpenJDK. There are no members that used those consts and should be simply killed even without changes. We can take bugs IF ANYONE EVER used it. I don't waste my time on "fixing" this.

	<span class='removed removed-method breaking' data-is-breaking>public virtual bool IsAnnotationPresent (Java.Lang.Class annotationClass);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void AddPropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void RemovePropertyChangeListener (Java.Beans.IPropertyChangeListener listener);</span>
	(in both Pack200.IPacker and Pack200.IUnpacker)
	<span class='removed removed-property breaking' data-is-breaking>public virtual bool IsDestroyed { get; }</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual void Destroy ();</span>

They are all api-merge bug: why does api-merge preserve this method as a default interface method?? It had been non-default in earlier API Levels, therefore api-merge must generate this method as non-default.

	<span class='added added-interface breaking' data-is-breaking>IAnnotatedElement</span>

This is new in java.lang.reflect.GenericDeclaration interface and should also be part of huge Harmony - OpenJDK migration. And unlike other new additional interfaces, those methods in AnnotatedElement are not default, so they are indeed breaking changes.

At this state, I don't think there is anything we can help the situation. We cannot remove this base interface type because that will generate JCW  that doesn't compile.

The only idea I can think of is to completely kill this type. It's just like we give up EntityIterator.

	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Position (long newPosition);</span>
	<span class='removed removed-method breaking' data-is-breaking>public virtual FileChannel Truncate (long size);</span>
	<span class='removed removed-method breaking' data-is-breaking>public System.Threading.Tasks.Task&lt;FileChannel&gt; TruncateAsync (long size);</span>

This was actually newly introduced breakage for OpenJDK migration too. FileChannel now implements SeekableByteChannel, which never existed, and they require those methods to return ISeekableByteChannel in C#, not FileChannel whereas FileChannel **is** ISeekableByteChannel.

So they are changed in the metadata fixup, but then this breakage. Now Position() and Truncate() are added as explicit interface implementation.

However, what can we do for TruncateAsync() ? NOTHING! It is (semi-)automatically generated by `generateAsyncWrapper='true'` which is NOT defined in the interface and therefore it cannot be explicitly implemented. And it's all about return types.

	<span class='added added-interface breaking' data-is-breaking>Javax.Security.Auth.IDestroyable</span>

This should not be reported because all those interface methods are default!

	<h3>Removed Type <span class='breaking' data-is-breaking>Android.Service.Quicksettings.TileState</span></h3></div> <!-- end namespace Android.Service.Quicksettings -->

I explicitly removed this. It had been marked as [Obsolete].
@atsushieno
Copy link
Contributor Author

atsushieno commented Aug 22, 2017

Why have you been keeping this pending while you have been asking me to merge a handful of your generator fixes without tests?

@jonpryor
Copy link
Member

Why have you been keeping this pending while you have been asking me to merge a handful of your generator fixes without tests?

Good question. :-(

"The perfect is the enemy of the good"...

@jonpryor jonpryor merged commit bac28ab into dotnet:master Aug 22, 2017
jonpryor added a commit to jonpryor/java.interop that referenced this pull request Mar 16, 2022
jonpryor added a commit that referenced this pull request Mar 16, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Apr 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants