Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[generator] Add support for const fields on interfaces (#439)
Add support for Java-side interface constants to be optionally bound using C# 8.0's new default interface member support. This is feature-flagged behind the `--lang-features=interface-constants` option (off by default): generator --lang-features=interface-constants ... Here is an example of what is generated from `Mono.Android.dll`: // Metadata.xml XPath interface reference: path="/api/package[@name='android.os']/interface[@name='Parcelable']" [Register ("android/os/Parcelable", "", "Android.OS.IParcelableInvoker", ApiSince = 1)] public partial interface IParcelable : IJavaObject { + // Metadata.xml XPath field reference: path="/api/package[@name='android.os']/interface[@name='Parcelable']/field[@name='CONTENTS_FILE_DESCRIPTOR']" + [Register ("CONTENTS_FILE_DESCRIPTOR")] + public const int ContentsFileDescriptor = (int) 1; // Metadata.xml XPath method reference: path="/api/package[@name='android.os']/interface[@name='Parcelable']/method[@name='describeContents' and count(parameter)=0]" [Register ("describeContents", "()I", "GetDescribeContentsHandler:Android.OS.IParcelableInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")] int DescribeContents (); // Metadata.xml XPath method reference: path="/api/package[@name='android.os']/interface[@name='Parcelable']/method[@name='writeToParcel' and count(parameter)=2 and parameter[1][@type='android.os.Parcel'] and parameter[2][@type='int']]" [Register ("writeToParcel", "(Landroid/os/Parcel;I)V", "GetWriteToParcel_Landroid_os_Parcel_IHandler:Android.OS.IParcelableInvoker, Mono.Android, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null")] void WriteToParcel (Android.OS.Parcel dest, [global::Android.Runtime.GeneratedEnum] Android.OS.ParcelableWriteFlags flags); } There are several Android interfaces defined that only contain constants. Without Default-Interface-Methods, we have not been generating these interfaces because there was nothing we could generate for them. (These are referred to as `IsConstSugar`). Now we generate them, but they do not have `[Register]` on the interface and do not inherit from `IJavaObject` since they are not used for Java interop, e.g. [`android.icu.lang.UProperty.NameChoice][0]: [0]: https://developer.android.com/reference/android/icu/lang/UProperty.NameChoice // Metadata.xml XPath interface reference: path="/api/package[@name='android.icu.lang']/interface[@name='UProperty.NameChoice']" public partial interface IUPropertyNameChoice { // Metadata.xml XPath field reference: path="/api/package[@name='android.icu.lang']/interface[@name='UProperty.NameChoice']/field[@name='LONG']" [Register ("LONG")] public const int Long = (int) 1; // Metadata.xml XPath field reference: path="/api/package[@name='android.icu.lang']/interface[@name='UProperty.NameChoice']/field[@name='SHORT']" [Register ("SHORT")] public const int Short = (int) 0; } Here is the diff of this change run on `Mono.Android.dll`: https://gist.github.com/jpobst/7aa0bb1a01975a56038cb7ab12ecdb1c
- Loading branch information
Showing
16 changed files
with
334 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
...s/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteConstSugarInterfaceFields.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
public partial interface IMyInterface { | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyConstantField']" | ||
[Register ("MyConstantField")] | ||
public const int MyConstantField = (int) 7; | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyConstantStringField']" | ||
[Register ("MyConstantStringField")] | ||
public const string MyConstantStringField = (string) "hello"; | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyDeprecatedField']" | ||
[Register ("MyDeprecatedField")] | ||
[Obsolete ("")] | ||
public const int MyDeprecatedField = (int) 7; | ||
|
||
} | ||
|
14 changes: 14 additions & 0 deletions
14
...rator/Tests/Unit-Tests/CodeGeneratorExpectedResults/JavaInterop1/WriteInterfaceFields.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")] | ||
public partial interface IMyInterface : IJavaObject { | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyConstantField']" | ||
[Register ("MyConstantField")] | ||
public const int MyConstantField = (int) 7; | ||
|
||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]" | ||
[Register ("DoSomething", "()V", "GetDoSomethingHandler:java.code.IMyInterfaceInvoker, ")] | ||
void DoSomething (); | ||
|
||
} | ||
|
18 changes: 18 additions & 0 deletions
18
...Unit-Tests/CodeGeneratorExpectedResults/XamarinAndroid/WriteConstSugarInterfaceFields.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
public partial interface IMyInterface { | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyConstantField']" | ||
[Register ("MyConstantField")] | ||
public const int MyConstantField = (int) 7; | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyConstantStringField']" | ||
[Register ("MyConstantStringField")] | ||
public const string MyConstantStringField = (string) "hello"; | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyDeprecatedField']" | ||
[Register ("MyDeprecatedField")] | ||
[Obsolete ("")] | ||
public const int MyDeprecatedField = (int) 7; | ||
|
||
} | ||
|
14 changes: 14 additions & 0 deletions
14
...tor/Tests/Unit-Tests/CodeGeneratorExpectedResults/XamarinAndroid/WriteInterfaceFields.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// Metadata.xml XPath interface reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']" | ||
[Register ("java/code/IMyInterface", "", "java.code.IMyInterfaceInvoker")] | ||
public partial interface IMyInterface : IJavaObject { | ||
|
||
// Metadata.xml XPath field reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/field[@name='MyConstantField']" | ||
[Register ("MyConstantField")] | ||
public const int MyConstantField = (int) 7; | ||
|
||
// Metadata.xml XPath method reference: path="/api/package[@name='java.code']/interface[@name='IMyInterface']/method[@name='DoSomething' and count(parameter)=0]" | ||
[Register ("DoSomething", "()V", "GetDoSomethingHandler:java.code.IMyInterfaceInvoker, ")] | ||
void DoSomething (); | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using System; | ||
using System.IO; | ||
using System.Reflection; | ||
using System.Text; | ||
using MonoDroid.Generation; | ||
using NUnit.Framework; | ||
|
||
namespace generatortests.Unit_Tests | ||
{ | ||
abstract class CodeGeneratorTestBase | ||
{ | ||
protected CodeGenerator generator; | ||
protected StringBuilder builder; | ||
protected StringWriter writer; | ||
protected CodeGenerationOptions options; | ||
|
||
[SetUp] | ||
public void SetUp () | ||
{ | ||
builder = new StringBuilder (); | ||
writer = new StringWriter (builder); | ||
options = CreateOptions (); | ||
|
||
generator = options.CreateCodeGenerator (writer); | ||
} | ||
|
||
[TearDown] | ||
public void TearDown () | ||
{ | ||
writer.Dispose (); | ||
} | ||
|
||
protected virtual CodeGenerationOptions CreateOptions () | ||
{ | ||
return new CodeGenerationOptions { | ||
CodeGenerationTarget = Target, | ||
}; | ||
} | ||
|
||
protected abstract Xamarin.Android.Binder.CodeGenerationTarget Target { get; } | ||
|
||
// Get the test results from "Common" for tests with the same results regardless of Target | ||
protected string GetExpected (string testName) | ||
{ | ||
var root = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location); | ||
|
||
return File.ReadAllText (Path.Combine (root, "Unit-Tests", "CodeGeneratorExpectedResults", "Common", $"{testName}.txt")).NormalizeLineEndings (); | ||
} | ||
|
||
// Get the test results from "JavaInterop1" or "XamarinAndroid" for tests with the different results per Target | ||
protected string GetTargetedExpected (string testName) | ||
{ | ||
var target = Target.ToString (); | ||
var root = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location); | ||
|
||
return File.ReadAllText (Path.Combine (root, "Unit-Tests", "CodeGeneratorExpectedResults", target, $"{testName}.txt")).NormalizeLineEndings (); | ||
} | ||
} | ||
} |
Oops, something went wrong.