Skip to content

Commit

Permalink
[Xamarin.Android.Build.Tasks] Add MSBuild support for DIM.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpobst committed Aug 26, 2019
1 parent 04a4308 commit e3e3b86
Show file tree
Hide file tree
Showing 15 changed files with 446 additions and 0 deletions.
7 changes: 7 additions & 0 deletions build-tools/automation/azure-pipelines.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,13 @@ stages:
project: tests/EmbeddedDSOs/EmbeddedDSO/EmbeddedDSO.csproj
testResultsFiles: TestResult-Xamarin.Android.EmbeddedDSO_Test.nunit-$(ApkTestConfiguration).xml

- template: yaml-templates/apk-instrumentation.yaml
parameters:
configuration: $(ApkTestConfiguration)
testName: Xamarin.Android.DefaultInterfaceMethods-Tests
project: tests/CodeGen-Binding/Xamarin.Android.DefaultInterfaceMethods-Tests/Xamarin.Android.DefaultInterfaceMethods-Tests.csproj
testResultsFiles: TestResult-Xamarin.Android.DefaultInterfaceMethods-Tests-$(ApkTestConfiguration).xml

- task: MSBuild@1
displayName: run Xamarin.Forms-Performance-Integration
inputs:
Expand Down
29 changes: 29 additions & 0 deletions src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public class BindingsGenerator : AndroidToolTask
[Required]
public string MonoAndroidFrameworkDirectories { get; set; }

public string LangVersion { get; set; }

public bool EnableInterfaceMembersPreview { get; set; }

public ITaskItem[] TransformFiles { get; set; }
public ITaskItem[] ReferencedManagedLibraries { get; set; }
public ITaskItem[] AnnotationsZipFiles { get; set; }
Expand Down Expand Up @@ -131,6 +135,9 @@ protected override string GenerateCommandLineCommands ()
if (UseShortFileNames)
cmd.AppendSwitch ("--use-short-file-names");

if (EnableInterfaceMembersPreview && SupportsCSharp8)
cmd.AppendSwitch ("--lang-features=interface-constants,default-interface-methods");

return cmd.ToString ();
}

Expand All @@ -142,5 +149,27 @@ protected override string GenerateFullPathToTool ()
{
return Path.Combine (ToolPath, ToolExe);
}

bool SupportsCSharp8 {
get {
// These are the values that pre-date C# 8. We assume any
// new value we encounter is something that supports it.
switch (LangVersion) {
case "7.3":
case "7.2":
case "7.1":
case "7":
case "6":
case "5":
case "4":
case "3":
case "ISO-2":
case "ISO-1":
return false;
}

return true;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -510,5 +510,63 @@ public void DesignTimeBuild (string classParser)
}
}
}

[Test]
[TestCaseSource (nameof (ClassParseOptions))]
public void BindDefaultInterfaceMethods (string classParser)
{
var proj = new XamarinAndroidBindingProject {
IsRelease = true,
};

// The sources for the .jar is in the jar itself.
string classesJarBase64 = @"
UEsDBBQACAgIANWk6UwAAAAAAAAAAAAAAAAJAAQATUVUQS1JTkYv/soAAAMAUEsHCAAAAAACAAAAAAA
AAFBLAwQUAAgICADVpOlMAAAAAAAAAAAAAAAAFAAAAE1FVEEtSU5GL01BTklGRVNULk1G803My0xLLS
7RDUstKs7Mz7NSMNQz4OVyLkpNLElN0XWqBAlY6BnEG5obKmj4FyUm56QqOOcXFeQXJZYA1WvycvFyA
QBQSwcIFGFrLUQAAABFAAAAUEsDBAoAAAgAAK2k6UwAAAAAAAAAAAAAAAAEAAAAY29tL1BLAwQKAAAI
AACtpOlMAAAAAAAAAAAAAAAADAAAAGNvbS94YW1hcmluL1BLAwQKAAAIAACwpOlMAAAAAAAAAAAAAAA
AEQAAAGNvbS94YW1hcmluL3Rlc3QvUEsDBBQACAgIAJmk6UwAAAAAAAAAAAAAAAAuAAAAY29tL3hhbW
FyaW4vdGVzdC9EZWZhdWx0SW50ZXJmYWNlTWV0aG9kcy5jbGFzc3WOvU7DMBSFjxsnKeWnXUE8QLrgh
ScAhBSJnwHE7qQ3JVUSC8dGFc/EwsrAA/BQiOuqLKnw8Pn4+LuWv38+vwCcY5biKMVUIKqMYWbzXEBe
mgUJTG/qju58W5B91EXDTbIkd6HtX3jj0G+DzPL5E28v3q8FJg/G25Ku6zB1ekWV9o3LO0e20iXdkns
2i/5spV+1QFaaVq11q23dKUe9U//4ArMwoRrdLdV9saLSJQICI4QVc4ogmTGfThBugFH0zuR/MpNNE7
x015NDL3C868VDL2XuYbL1joMTjI+BNpYC+/xcaA820uEvUEsHCIw1aijpAAAAhQEAAFBLAwQUAAgIC
ACYpOlMAAAAAAAAAAAAAAAAHAAAAERlZmF1bHRJbnRlcmZhY2VNZXRob2RzLmphdmF1zLEOwiAQBuCd
p7hRl0Zd2YyLgw9xwlGJFCocTWPTdxdSHarxxv///utR3bElUKFrRuwwWt8wJZZC9PnqrALrmaJBRXA
ig9nx+RNciG9BJzEJKKeXtnowIcBmCxNE4hw97CTMP6glPmJcuf1f91y5w7cbgtWQ3rCOBnSZymJhNX
nkPJYnUsziBVBLBwgzfz2miQAAAPUAAABQSwECFAAUAAgICADVpOlMAAAAAAIAAAAAAAAACQAEAAAAA
AAAAAAAAAAAAAAATUVUQS1JTkYv/soAAFBLAQIUABQACAgIANWk6UwUYWstRAAAAEUAAAAUAAAAAAAA
AAAAAAAAAD0AAABNRVRBLUlORi9NQU5JRkVTVC5NRlBLAQIKAAoAAAgAAK2k6UwAAAAAAAAAAAAAAAA
EAAAAAAAAAAAAAAAAAMMAAABjb20vUEsBAgoACgAACAAAraTpTAAAAAAAAAAAAAAAAAwAAAAAAAAAAA
AAAAAA5QAAAGNvbS94YW1hcmluL1BLAQIKAAoAAAgAALCk6UwAAAAAAAAAAAAAAAARAAAAAAAAAAAAA
AAAAA8BAABjb20veGFtYXJpbi90ZXN0L1BLAQIUABQACAgIAJmk6UyMNWoo6QAAAIUBAAAuAAAAAAAA
AAAAAAAAAD4BAABjb20veGFtYXJpbi90ZXN0L0RlZmF1bHRJbnRlcmZhY2VNZXRob2RzLmNsYXNzUEs
BAhQAFAAICAgAmKTpTDN/PaaJAAAA9QAAABwAAAAAAAAAAAAAAAAAgwIAAERlZmF1bHRJbnRlcmZhY2
VNZXRob2RzLmphdmFQSwUGAAAAAAcABwDOAQAAVgMAAAAA
";
proj.Jars.Add (new AndroidItem.EmbeddedJar ("dim.jar") {
BinaryContent = () => Convert.FromBase64String (classesJarBase64)
});

proj.AndroidClassParser = classParser;

proj.SetProperty ("EnableInterfaceMembersPreview", "True");
proj.SetProperty ("LangVersion", "preview");

using (var b = CreateDllBuilder (Path.Combine ("temp", TestName), false, false)) {
proj.NuGetRestore (b.ProjectDirectory);
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");

string asmpath = Path.GetFullPath (Path.Combine (Path.GetDirectoryName (new Uri (GetType ().Assembly.CodeBase).LocalPath), b.ProjectDirectory, b.Output.OutputPath, (proj.AssemblyName ?? proj.ProjectName) + ".dll"));
Assert.IsTrue (File.Exists (asmpath), "assembly does not exist");

var cs = b.Output.GetIntermediaryAsText (Path.Combine ("generated", "src", "Com.Xamarin.Test.IDefaultInterfaceMethods.cs"));
Assert.IsTrue (cs.Contains ("int Quux ();"), "Quux not generated.");
Assert.IsTrue (cs.Contains ("virtual unsafe int Foo ()"), "Foo not generated.");
Assert.IsTrue (cs.Contains ("virtual unsafe int Bar {"), "Bar not generated.");
Assert.IsTrue (cs.Contains ("set {"), "(Baz) setter not generated.");
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved.
ToolPath="$(MonoAndroidToolsDirectory)"
ToolExe="$(BindingsGeneratorToolExe)"
UseShortFileNames="$(UseShortGeneratorFileNames)"
LangVersion="$(LangVersion)"
EnableInterfaceMembersPreview="$(EnableInterfaceMembersPreview)"
/>

<!-- Write a flag so we won't redo this target if nothing changed -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.xamarin.test;

public interface DefaultMethodsInterface
{
default int foo () { return 0; }
default int getBar () { return 2; }
default void setBar (int value) { }
default int toImplement () { throw new UnsupportedOperationException (); }
default int invokeFoo () { return foo (); }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.xamarin.test;

public class EmptyOverrideClass implements DefaultMethodsInterface
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.xamarin.test;

public class ImplementedOverrideClass implements DefaultMethodsInterface
{
@Override
public int foo () {
return 6;
}

@Override
public int getBar () {
return 100;
}

@Override
public void setBar (int value) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{D360FDF3-F1CE-4698-9351-CC9D4502DF5C}</ProjectGuid>
<ProjectTypeGuids>{10368E6C-D01B-4462-8E8B-01FC667A7035};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TemplateGuid>{77efb91c-a7e9-4b0e-a7c5-31eeec3c6d46}</TemplateGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Xamarin.Android.DefaultInterfaceMethods_Lib</RootNamespace>
<AssemblyName>Xamarin.Android.DefaultInterfaceMethods-Lib</AssemblyName>
<FileAlignment>512</FileAlignment>
<AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
<AndroidClassParser>class-parse</AndroidClassParser>
<AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<LangVersion>preview</LangVersion>
<EnableInterfaceMembersPreview>True</EnableInterfaceMembersPreview>
<_JavacSourceVersion>1.8</_JavacSourceVersion>
<_JavacTargetVersion>1.8</_JavacTargetVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>portable</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>portable</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
<Reference Include="System" />
<Reference Include="System.Core" />
</ItemGroup>
<ItemDefinitionGroup>
<TestJarEntry>
<OutputFile>Jars/dim-test.jar</OutputFile>
</TestJarEntry>
</ItemDefinitionGroup>
<ItemGroup>
<TestJarEntry Include="Jars\ImplementedOverrideClass.java" />
<TestJarEntry Include="Jars\EmptyOverrideClass.java" />
<TestJarEntry Include="Jars\DefaultMethodsInterface.java" />
</ItemGroup>
<ItemGroup>
<EmbeddedJar Include="Jars/dim-test.jar" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.targets" />
<Import Project="..\..\..\build-tools\scripts\Jar.targets" />
<PropertyGroup>
<BuildDependsOn>
BuildTestJarFile;
$(BuildDependsOn)
</BuildDependsOn>
</PropertyGroup>
<PropertyGroup>
<CleanDependsOn>
CleanTestJarFile;
$(CleanDependsOn);
</CleanDependsOn>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using Com.Xamarin.Test;
using Java.Lang;
using NUnit.Framework;

namespace Xamarin.Android.DefaultInterfaceMethodsTests
{
[TestFixture]
public class DimTest
{
[Test]
public void TestDefaultInterfaceMethods ()
{
var empty = new EmptyOverrideClass ();
var iface = empty as IDefaultMethodsInterface;

Assert.AreEqual (0, iface.Foo ());
Assert.AreEqual (2, iface.Bar);
Assert.DoesNotThrow (() => iface.Bar = 5);

Assert.AreEqual (0, iface.InvokeFoo ());

Assert.Throws<UnsupportedOperationException> (() => iface.ToImplement ());
}

[Test]
public void TestOverriddenDefaultInterfaceMethods ()
{
var over = new ImplementedOverrideClass ();
var iface = over as IDefaultMethodsInterface;

Assert.AreEqual (6, over.Foo ());
Assert.AreEqual (100, over.Bar);
Assert.DoesNotThrow (() => over.Bar = 5);

Assert.AreEqual (6, iface.InvokeFoo ());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Android.App;
using Android.OS;
using Xamarin.Android.NUnitLite;
using System.Reflection;

namespace Xamarin.Android.DefaultInterfaceMethods_Tests
{
[Activity (Label = "Xamarin.Android.DefaultInterfaceMethods-Tests", MainLauncher = true)]
public class MainActivity : TestSuiteActivity
{
protected override void OnCreate (Bundle savedInstanceState)
{
AddTest (Assembly.GetExecutingAssembly ());

base.OnCreate (savedInstanceState);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="xamarin.android.defaultinterfacemethods_tests" android:installLocation="auto">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<application android:allowBackup="true" android:label="DimTests" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Android.App;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Xamarin.Android.DefaultInterfaceMethods_Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Xamarin.Android.DefaultInterfaceMethods_Tests")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Reflection;

using Android.App;
using Android.Runtime;
using Xamarin.Android.NUnitLite;

namespace Xamarin.Android.DefaultInterfaceMethods_Tests
{
[Instrumentation (Name="xamarin.android.dimtests.TestInstrumentation")]
public class TestInstrumentation : TestSuiteInstrumentation {

public TestInstrumentation (IntPtr handle, JniHandleOwnership transfer)
: base (handle, transfer)
{
}

protected override void AddTests ()
{
AddTest (Assembly.GetExecutingAssembly ());
}
}
}

Loading

0 comments on commit e3e3b86

Please sign in to comment.