From 3bd19e0d44c309b9c0347b3482ee528d6efbbf99 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 29 Oct 2020 13:52:36 -0400 Subject: [PATCH 1/9] [Mono.Android] Generate Mono.Android.xml; @(JavaSourceJar) on JDK11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/xamarin/xamarin-android/issues/4789 Context: https://github.com/xamarin/java.interop/pull/687 Context: https://github.com/xamarin/xamarin-android/issues/5200 What do we want? Updated documentation! How do we get that? Uh… Historically, [Xamarin.Android API docs][0] were produced by parsing Android's HTML documentation from `docs-24_r01.zip` and converting it into [**mdoc**(5) documentation][1] via [`tools/javadoc2mdoc`]. The problem is that Google hasn't released an updated `docs*.zip` package since API-24 (~6 years ago), and thus our documentation is woefully out of date. We could have scraped developer.android.com/reference within that time frame, but web scraping is annoying, and we'd still have to deal with the pain of parsing HTML. There is an alternative, though: with API-30, there is a new `sources` package which contains the Java source code used for the API level, which in turn contains Javadoc source code comments. Previous API levels similarly contained an `android-stubs-src.jar` file which likewise contained Java source code containing Javadoc comments. The new approach is to: 1. Update `build-tools/xaprepare` to install the `sources` package. 2. Use [`java-source-tool.jar`][2] to parse the Java source code, creating an `android-javadoc.xml` file. 3. [Update `generator`][3] to consume `android-javadoc.xml` and convert the Javadocs into [C# XML documentation comments][4]. 4. Update `src/Mono.Android` so that `generator` will emit C# XML doc comments, and then produce a `Mono.Android.xml` file. The result is a `Mono.Android.xml` file which contains imported Android Javadoc documentation, e.g. Mono.Android Class Object is the root of the class hierarchy. Class Object is the root of the class hierarchy. … "Later", `Mono.Android.xml` can then be used alongside [`mdoc update --import=Mono.Android.xml`][5] to update our published API documentation. Finally, commit 380e95e3, which added support for JDK 11, *broke* support for `@(JavaSourceJar)` when running under JDK 11, as JDK 11's Javadoc HTML output differs from what we expect. With the new `java-source-utils.jar` and `generator --with-javadoc-xml=FILE` infrastructure in place, we can reasonably address this breakage under JDK 11, fixing Issue #4789: Update `Xamarin.Android.Bindings.Core.targets` so that before invoking `generator`, we first run `java-source-utils.jar` on the `@(JavaSourceJar)` files, producing Javadoc XML files. The `` task in turn is updated to accept a new `BindingsGenerator.JavadocXml` property, which is converted into a `generator --with-javadoc-xml=FILE` option. The `@(JavaSourceJar)` item group is "extended" to support the following item metadata: * `%(CopyrightFile)`: A path to a file that contains copyright information for the Javadoc contents, which will be appended to all imported documentation. * `%(UrlPrefix)`: A URL prefix to support linking to online documentation within imported documentation. * `%(UrlStyle)`: The "style" of URLs to generate when linking to online documentation. Only one style is currently supported: `developer.android.com/reference@2020-Nov`. For .NET 6 ("One .NET") integration purposes, provide a default item group of `@(JavaSourceJar)` which includes `**\*-source?.jar` and `**\*-src.jar`. This will allow `dotnet build` of an "Android Java Library Binding" project (`dotnet new android-bindinglib`) to automatically process `.java` source code for documentation translation purposes. Add `Java.Interop.Tools.Generator.dll` to the `Microsoft.Android.Sdk*.nupkg` file, as it is an assembly dependency of `generator.dll`. (Not sure why this didn't previously fail…) Finally, add a new `$(_UseLegacyJavadocImport)` MSBuild property which *disables* use of `java-source-utils.jar` for Javadoc importing, and instead use the previous, legacy, doesn't work on JDK 11, approach of using `javadoc` and HTML parsing. This shouldn't be needed, but just in case it *is* needed… [0]: https://github.com/xamarin/android-api-docs [1]: http://docs.go-mono.com/?link=man%3amdoc(5) [2]: https://github.com/xamarin/java.interop/commit/69e1b80afd81ac502494e4bc2a2de75f5171c73f [3]: https://github.com/xamarin/java.interop/pull/687 [4]: https://docs.microsoft.com/dotnet/csharp/codedoc [5]: http://docs.go-mono.com/?link=man%3amdoc-update(1) --- .gitmodules | 4 +- Xamarin.Android.sln | 9 +- .../create-packs/Microsoft.Android.Sdk.proj | 1 + .../installers/create-installers.targets | 3 + .../Dependencies/AndroidToolchain.cs | 2 + .../ThirdPartyNotices/Java.Interop.cs | 13 ++ external/Java.Interop | 2 +- src/Mono.Android/Mono.Android.csproj | 11 ++ src/Mono.Android/Mono.Android.targets | 48 ++++- src/Mono.Android/javadoc-copyright.xml | 5 + .../Xamarin.Android.Bindings.Core.targets | 23 +++ ...rin.Android.Bindings.Documentation.targets | 10 +- .../Sdk/AutoImport.props | 3 +- .../Tasks/Generator.cs | 8 + .../Tasks/JavaSourceUtils.cs | 181 ++++++++++++++++++ .../BindingBuildTest.cs | 31 +-- .../Xamarin.Android.Build.Tests/XASdkTests.cs | 6 +- .../Xamarin.Android.McwGen-Tests.csproj | 4 + .../Xamarin.Android.McwGen-Tests.targets | 11 ++ .../android/DefaultMethodsInterface.java | 1 + 20 files changed, 333 insertions(+), 43 deletions(-) create mode 100644 src/Mono.Android/javadoc-copyright.xml create mode 100644 src/Xamarin.Android.Build.Tasks/Tasks/JavaSourceUtils.cs diff --git a/.gitmodules b/.gitmodules index 02c34fcbc01..f7ad716dd35 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,8 +12,8 @@ branch = master [submodule "external/Java.Interop"] path = external/Java.Interop - url = https://github.com/xamarin/java.interop.git - branch = master + url = https://github.com/jonpryor/java.interop.git + branch = jonp-generator-javadoc-xml [submodule "external/lz4"] path = external/lz4 url = https://github.com/lz4/lz4.git diff --git a/Xamarin.Android.sln b/Xamarin.Android.sln index 5f4525a319d..f672d86ece7 100644 --- a/Xamarin.Android.sln +++ b/Xamarin.Android.sln @@ -142,6 +142,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xamarin.SourceWriter", "ext EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "apksigner", "src\apksigner\apksigner.csproj", "{9A9EF774-6EA6-414F-9D2F-DCD66C56B92A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "java-source-utils", "external\Java.Interop\tools\java-source-utils\java-source-utils.csproj", "{37FCD325-1077-4603-98E7-4509CAD648D6}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Xamarin.Android.NamingCustomAttributes\Xamarin.Android.NamingCustomAttributes.projitems*{3f1f2f50-af1a-4a5a-bedb-193372f068d7}*SharedItemsImports = 4 @@ -376,7 +378,7 @@ Global {071D9096-65BB-4359-822E-09788439F210}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU {071D9096-65BB-4359-822E-09788439F210}.Debug|AnyCPU.Build.0 = Debug|Any CPU {071D9096-65BB-4359-822E-09788439F210}.Release|AnyCPU.ActiveCfg = Release|Any CPU - {071D9096-65BB-4359-822E-09788439F210}.Release|AnyCPU.Build.0 = Release|Any CPU EndGlobalSection + {071D9096-65BB-4359-822E-09788439F210}.Release|AnyCPU.Build.0 = Release|Any CPU {2CE4CD4B-B7B7-4EAE-A9BE-2699824D6096}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU {2CE4CD4B-B7B7-4EAE-A9BE-2699824D6096}.Debug|AnyCPU.Build.0 = Debug|Any CPU {2CE4CD4B-B7B7-4EAE-A9BE-2699824D6096}.Release|AnyCPU.ActiveCfg = Release|Any CPU @@ -389,6 +391,10 @@ Global {9A9EF774-6EA6-414F-9D2F-DCD66C56B92A}.Debug|AnyCPU.Build.0 = Debug|Any CPU {9A9EF774-6EA6-414F-9D2F-DCD66C56B92A}.Release|AnyCPU.ActiveCfg = Release|Any CPU {9A9EF774-6EA6-414F-9D2F-DCD66C56B92A}.Release|AnyCPU.Build.0 = Release|Any CPU + {37FCD325-1077-4603-98E7-4509CAD648D6}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU + {37FCD325-1077-4603-98E7-4509CAD648D6}.Debug|AnyCPU.Build.0 = Debug|Any CPU + {37FCD325-1077-4603-98E7-4509CAD648D6}.Release|AnyCPU.ActiveCfg = Release|Any CPU + {37FCD325-1077-4603-98E7-4509CAD648D6}.Release|AnyCPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -454,6 +460,7 @@ Global {2CE4CD4B-B7B7-4EAE-A9BE-2699824D6096} = {04E3E11E-B47D-4599-8AFC-50515A95E715} {86A8DEFE-7ABB-4097-9389-C249581E243D} = {04E3E11E-B47D-4599-8AFC-50515A95E715} {9A9EF774-6EA6-414F-9D2F-DCD66C56B92A} = {04E3E11E-B47D-4599-8AFC-50515A95E715} + {37FCD325-1077-4603-98E7-4509CAD648D6} = {864062D3-A415-4A6F-9324-5820237BA058} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {53A1F287-EFB2-4D97-A4BB-4A5E145613F6} diff --git a/build-tools/create-packs/Microsoft.Android.Sdk.proj b/build-tools/create-packs/Microsoft.Android.Sdk.proj index 9240ef79571..84034a5f427 100644 --- a/build-tools/create-packs/Microsoft.Android.Sdk.proj +++ b/build-tools/create-packs/Microsoft.Android.Sdk.proj @@ -76,6 +76,7 @@ core workload sdk packs imported by Microsoft.NET.Workload.Android. <_PackageFiles Include="$(ToolsSourceDir)**" PackagePath="tools" /> <_PackageFiles Include="$(NetCoreAppToolsSourceDir)generator.dll" PackagePath="tools" /> <_PackageFiles Include="$(NetCoreAppToolsSourceDir)generator.runtimeconfig.json" PackagePath="tools" /> + <_PackageFiles Include="$(NetCoreAppToolsSourceDir)Java.Interop.Tools.Generator.dll" PackagePath="tools" /> <_PackageFiles Include="$(NetCoreAppToolsSourceDir)javadoc-to-mdoc.dll" PackagePath="tools" /> <_PackageFiles Include="$(NetCoreAppToolsSourceDir)javadoc-to-mdoc.runtimeconfig.json" PackagePath="tools" /> <_PackageFiles Include="$(XAInstallPrefix)xbuild-frameworks\Microsoft.Android\Version*" PackagePath="tools" /> diff --git a/build-tools/installers/create-installers.targets b/build-tools/installers/create-installers.targets index dcc7c1e4ffa..90404e54e4f 100644 --- a/build-tools/installers/create-installers.targets +++ b/build-tools/installers/create-installers.targets @@ -132,6 +132,7 @@ <_MSBuildFiles Include="$(MSBuildSrcDir)\illinkanalyzer.pdb" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Irony.dll" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\java-interop.jar" /> + <_MSBuildFiles Include="$(MSBuildSrcDir)\java-source-utils.jar" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\javadoc-to-mdoc.exe" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\javadoc-to-mdoc.pdb" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Interop.dll" /> @@ -149,6 +150,8 @@ <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Interop.Tools.Generator.pdb" ExcludeFromAndroidNETSdk="true" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Interop.Tools.JavaCallableWrappers.dll" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Interop.Tools.JavaCallableWrappers.pdb" /> + <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Interop.Tools.JavaSource.dll" /> + <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Interop.Tools.JavaSource.pdb" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Runtime.Environment.dll" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Runtime.Environment.pdb" /> <_MSBuildFiles Include="$(MSBuildSrcDir)\Java.Runtime.Environment.dll.config" Condition=" '$(HostOS)' != 'Windows' " /> diff --git a/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs b/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs index b2286001e72..6266f200528 100644 --- a/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs +++ b/build-tools/xaprepare/xaprepare/ConfigAndData/Dependencies/AndroidToolchain.cs @@ -62,6 +62,8 @@ public AndroidToolchain () new AndroidPlatformComponent ("platform-29_r01", apiLevel: "29", pkgRevision: "1"), new AndroidPlatformComponent ("platform-30_r01", apiLevel: "30", pkgRevision: "1"), + new AndroidToolchainComponent ("sources-30_r01", destDir: Path.Combine ("platforms", $"android-30", "src"), pkgRevision: "1", dependencyType: AndroidToolchainComponentType.BuildDependency), + new AndroidToolchainComponent ("docs-24_r01", destDir: "docs", pkgRevision: "1", dependencyType: AndroidToolchainComponentType.BuildDependency), new AndroidToolchainComponent ("android_m2repository_r47", destDir: Path.Combine ("extras", "android", "m2repository"), pkgRevision: "47.0.0", dependencyType: AndroidToolchainComponentType.BuildDependency), new AndroidToolchainComponent ($"x86_64-29_r07-{osTag}", destDir: Path.Combine ("system-images", "android-29", "default", "x86_64"), relativeUrl: new Uri ("sys-img/android/", UriKind.Relative), pkgRevision: "7", dependencyType: AndroidToolchainComponentType.EmulatorDependency), diff --git a/build-tools/xaprepare/xaprepare/ThirdPartyNotices/Java.Interop.cs b/build-tools/xaprepare/xaprepare/ThirdPartyNotices/Java.Interop.cs index c76d89ff01f..7128b63c9ca 100644 --- a/build-tools/xaprepare/xaprepare/ThirdPartyNotices/Java.Interop.cs +++ b/build-tools/xaprepare/xaprepare/ThirdPartyNotices/Java.Interop.cs @@ -12,6 +12,7 @@ class JavaInterop_External_Dependencies_Group : ThirdPartyNoticeGroup public override List Notices => new List { new JavaInterop_xamarin_Java_Interop_TPN (), new JavaInterop_gityf_crc_TPN (), + new JavaInterop_javaparser_javaparser_TPN (), new JavaInterop_jbevain_mono_linq_expressions_TPN (), new JavaInterop_mono_csharp_TPN (), new JavaInterop_mono_LineEditor_TPN (), @@ -69,6 +70,18 @@ POSSIBILITY OF SUCH DAMAGE. "; } + // via: https://github.com/xamarin/java.interop/blob/b588ef502d8d3b4c32e0ad731115e1b71fd56b5c/tools/java-source-utils/build.gradle#L33-L34 + class JavaInterop_javaparser_javaparser_TPN : ThirdPartyNotice + { + static readonly Uri url = new Uri ("https://github.com/javaparser/javaparser/"); + static readonly string licenseFile = Path.Combine (Configurables.Paths.ExternalJavaInteropDir, "LICENSE"); + + public override string LicenseFile => CommonLicenses.Apache20Path; + public override string Name => "javaparser/javaparser"; + public override Uri SourceUrl => url; + public override string LicenseText => String.Empty; + } + // git submodules of Java.Interop class JavaInterop_jbevain_mono_linq_expressions_TPN : ThirdPartyNotice { diff --git a/external/Java.Interop b/external/Java.Interop index 99897b24ead..ab032271e4b 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 99897b24eada3b68fa1eedae41efd15fbf128ae1 +Subproject commit ab032271e4b794976e170e5473e7f575202b0f58 diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 0eb1e062cd0..8b8c905f285 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -24,6 +24,16 @@ true + + + True + + + + $(OutputPath)Mono.Android.xml + CS1573;CS1591 + + MonoAndroid v1.0 @@ -347,6 +357,7 @@ + diff --git a/src/Mono.Android/Mono.Android.targets b/src/Mono.Android/Mono.Android.targets index 76f9388fb5f..13343a093f3 100644 --- a/src/Mono.Android/Mono.Android.targets +++ b/src/Mono.Android/Mono.Android.targets @@ -53,6 +53,50 @@ Replacements="@PACKAGE_VERSION@=$(_PackageVersion);@PACKAGE_VERSION_BUILD@=$(_PackageVersionBuild);@PACKAGE_HEAD_REV@=$(XAVersionHash);@PACKAGE_HEAD_BRANCH@=$(XAVersionBranch)"> + + <_JavaSourceUtilsJar>$(XAInstallPrefix)xbuild\Xamarin\Android\java-source-utils.jar + <_AndroidStableSrcDir>$(AndroidSdkDirectory)\platforms\android-$(AndroidLatestStableApiLevel)\src + <_AndroidJavadocXml>..\..\bin\Build$(Configuration)\android-javadoc.xml + + + + <_Doclink Include="--doc-copyright" /> + <_Doclink Include="$(MSBuildThisFileDirectory)javadoc-copyright.xml" /> + <_Doclink Include="--doc-url-prefix" /> + <_Doclink Include="https://developer.android.com/reference" /> + <_Doclink Include="--doc-url-style" /> + <_Doclink Include="developer.android.com/reference@2020-Nov" /> + + + <_AndroidSources Include="$(_AndroidStableSrcDir)\android\**\*.java" /> + <_AndroidSources Include="$(_AndroidStableSrcDir)\java\**\*.java" /> + <_AndroidSources Include="$(_AndroidStableSrcDir)\javax\**\*.java" /> + <_AndroidSources Include="$(_AndroidStableSrcDir)\org\**\*.java" /> + <_AndroidSources Remove="$(_AndroidStableSrcDir)\**\*.annotated.java" /> + + + <_Filenames>$(IntermediateOutputPath)\java-sources.txt + + + + <_JSIArg Include="-v" /> + <_JSIArg Include="--source "$(_AndroidStableSrcDir)"" /> + <_JSIArg Include="--output-javadoc "$(_AndroidJavadocXml)"" /> + <_JSIArg Include="@$(_Filenames)" /> + + + + --type-map-report=$(IntermediateOutputPath)mcw\type-mapping.txt <_Api>$(IntermediateOutputPath)mcw\api.xml <_Dirs>--enumdir=$(IntermediateOutputPath)mcw + <_WithJavadocXml Condition=" '$(IncludeAndroidJavadoc)' == 'True' ">"--with-javadoc-xml=$(_AndroidJavadocXml)" <_FullIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)')) <_LangFeatures>--lang-features=nullable-reference-types <_LangFeatures Condition="$(AndroidApiLevel) >= 30">$(_LangFeatures),default-interface-methods,nested-interface-types,interface-constants diff --git a/src/Mono.Android/javadoc-copyright.xml b/src/Mono.Android/javadoc-copyright.xml new file mode 100644 index 00000000000..7bca1d75e90 --- /dev/null +++ b/src/Mono.Android/javadoc-copyright.xml @@ -0,0 +1,5 @@ +Portions of this page are modifications based on work created and shared by the +Android Open Source Project + and used according to terms described in the +Creative Commons 2.5 Attribution License. + diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index 39e0400c9b3..acb671c4b8a 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -12,6 +12,7 @@ It is shared between "legacy" binding projects and .NET 5 projects. + @@ -21,6 +22,11 @@ It is shared between "legacy" binding projects and .NET 5 projects. <_GeneratorStampFile>$(IntermediateOutputPath)generator.stamp + + $(OutputPath)\$(AssemblyName).xml + $(NoWarn);CS1573;CS1591 + + @@ -42,6 +48,22 @@ It is shared between "legacy" binding projects and .NET 5 projects. + + + + - - <_JavadocSupported Condition=" $(_JdkVersion.StartsWith ('1.8')) ">True - - - + + diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs index f055c95b478..213205f14c2 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs @@ -52,6 +52,8 @@ public class BindingsGenerator : AndroidDotnetToolTask public ITaskItem[] ReferencedManagedLibraries { get; set; } public ITaskItem[] AnnotationsZipFiles { get; set; } + public ITaskItem[] JavadocXml { get; set; } + private List> transform_files = new List> (); public override bool RunTask () @@ -166,6 +168,12 @@ protected override string GenerateCommandLineCommands () if (EnableInterfaceMembersPreview && SupportsCSharp8) WriteLine (sw, "--lang-features=interface-constants,default-interface-methods"); + + if (JavadocXml != null) { + foreach (var xml in JavadocXml) { + WriteLine (sw, $"--with-javadoc-xml=\"{Path.GetFullPath (xml.ItemSpec)}\""); + } + } } cmd.AppendSwitch (ApiXmlInput); diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/JavaSourceUtils.cs b/src/Xamarin.Android.Build.Tasks/Tasks/JavaSourceUtils.cs new file mode 100644 index 00000000000..c8fb877e606 --- /dev/null +++ b/src/Xamarin.Android.Build.Tasks/Tasks/JavaSourceUtils.cs @@ -0,0 +1,181 @@ +// Copyright (C) 2012 Xamarin, Inc. All rights reserved. + +using System; +using System.Linq; +using System.IO; +using System.Reflection; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using Xamarin.Android.Tools; + +namespace Xamarin.Android.Tasks +{ + public class JavaSourceUtils : AndroidToolTask + { + public override string TaskPrefix => "JSU"; + + [Required] + public string MonoAndroidToolsDirectory { get; set; } + + [Required] + public string JavaSdkDirectory { get; set; } + + [Required] + public ITaskItem OutputDirectory { get; set; } + + [Required] + public ITaskItem[] InputFiles { get; set; } + + public ITaskItem[] References { get; set; } + + public ITaskItem[] BootClassPath { get; set; } + + public ITaskItem JavadocCopyrightFile { get; set; } + public string JavadocUrlPrefix { get; set; } + public string JavadocUrlStyle { get; set; } + + public string JavaOptions { get; set; } + + public string JavaMaximumHeapSize { get; set; } + + [Output] + public ITaskItem OutputJavadocXml { get; set; } + + string responseFilePath; + + public override bool RunTask () + { + if (InputFiles == null || InputFiles.Count () == 0) { + Log.LogCodedError ("XA1020", Properties.Resources.XA1020); + return false; + } + + if (References != null) + foreach (var path in References) + if (!Directory.Exists (path.ItemSpec) && !File.Exists (path.ItemSpec)) + Log.LogCodedError ("XA1022", Properties.Resources.XA1022, path.ItemSpec); + + if (Log.HasLoggedErrors) + return false; + + OutputJavadocXml = new TaskItem (Path.Combine (OutputDirectory.ItemSpec, GetOutputFileName (InputFiles)) + ".xml"); + + try { + return base.RunTask (); + } + finally { + File.Delete (responseFilePath); + } + } + + static string GetOutputFileName (ITaskItem[] items) => + Files.HashString ( + string.Join ("\n", items.Select (item => Path.GetFullPath (item.ItemSpec).Replace ('\\', '/')))); + + + protected override string GenerateCommandLineCommands () + { + responseFilePath = CreateResponseFile (); + + var cmd = new CommandLineBuilder (); + + // Add the JavaOptions if they are not null + // These could be any of the additional options + if (!string.IsNullOrEmpty (JavaOptions)) { + cmd.AppendSwitch (JavaOptions); + } + + if (!string.IsNullOrEmpty (JavaMaximumHeapSize)) { + cmd.AppendSwitchIfNotNull("-Xmx", JavaMaximumHeapSize); + } + + // Arguments sent to java.exe + cmd.AppendSwitchIfNotNull ("-jar ", Path.Combine (MonoAndroidToolsDirectory, "java-source-utils.jar")); + + cmd.AppendSwitch ($"@{responseFilePath}"); + + + return cmd.ToString (); + } + + string CreateResponseFile () + { + var responseFile = Path.GetTempFileName (); + + using var response = new StreamWriter (responseFile, append: false, encoding: MonoAndroidHelper.UTF8withoutBOM); + Log.LogDebugMessage ("[java-source-utils] response file contents: {0}", responseFile); + + if (BootClassPath != null && BootClassPath.Any ()) { + var classpath = string.Join (Path.PathSeparator.ToString (), BootClassPath.Select (p => Path.GetFullPath (p.ItemSpec))); + AppendArg (response, "--bootclasspath"); + AppendArg (response, classpath); + } + + if (References != null && References.Any ()) { + foreach (var r in References) { + if (Directory.Exists (r.ItemSpec)) { + AppendArg (response, "--source"); + AppendArg (response, Path.GetFullPath (r.ItemSpec)); + continue; + } + if (!File.Exists (r.ItemSpec)) { + Log.LogCodedError ("XA1022", Properties.Resources.XA1022, r.ItemSpec); + continue; + } + if (r.ItemSpec.EndsWith (".jar", StringComparison.OrdinalIgnoreCase)) { + AppendArg (response, "--jar"); + AppendArg (response, Path.GetFullPath (r.ItemSpec)); + continue; + } + if (r.ItemSpec.EndsWith (".aar", StringComparison.OrdinalIgnoreCase)) { + AppendArg (response, "--aar"); + AppendArg (response, Path.GetFullPath (r.ItemSpec)); + continue; + } + Log.LogError ($"Unsupported @(Reference) item: {r.ItemSpec}"); + } + } + AppendArg (response, "--output-javadoc"); + AppendArg (response, OutputJavadocXml.ItemSpec); + + if (!string.IsNullOrEmpty (JavadocCopyrightFile?.ItemSpec)) { + AppendArg (response, "--doc-copyright"); + AppendArg (response, Path.GetFullPath (JavadocCopyrightFile.ItemSpec)); + } + if (!string.IsNullOrEmpty (JavadocUrlPrefix)) { + AppendArg (response, "--doc-url-prefix"); + AppendArg (response, Path.GetFullPath (JavadocUrlPrefix)); + } + if (!string.IsNullOrEmpty (JavadocUrlStyle)) { + AppendArg (response, "--doc-link-style"); + AppendArg (response, Path.GetFullPath (JavadocUrlStyle)); + } + + foreach (var path in InputFiles) { + AppendArg (response, Path.GetFullPath (path.ItemSpec)); + } + + return responseFile; + + void AppendArg (TextWriter writer, string line) + { + writer.WriteLine (line); + Log.LogDebugMessage (line); + } + } + + protected override string ToolName { + get => "java-source-utils"; + } + + public override string ToolExe { + get { return OS.IsWindows ? "java.exe" : "java"; } + set { base.ToolExe = value; } + } + + protected override string GenerateFullPathToTool () + { + return Path.Combine (JavaSdkDirectory, "bin", ToolExe); + } + } +} diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs index fb638b52ef2..1accb8bda3d 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/BindingBuildTest.cs @@ -452,36 +452,11 @@ public void JavaSourceJar () BinaryContent = () => Convert.FromBase64String (InlineData.JavaSourcesJarBase64) }); Assert.IsTrue (bindingBuilder.Build (binding), "binding build should have succeeded"); - var jdkVersion = GetJdkVersion (); - if (jdkVersion > new Version (9, 0)) { - Assert.Ignore ("JDK 11 and @(JavaSourceJar) don't currently mix."); - return; - } - string xml = bindingBuilder.Output.GetIntermediaryAsText ("docs/Com.Xamarin.Android.Test.Msbuildtest/JavaSourceJarTest.xml"); - Assert.IsTrue (xml.Contains (" - name to display."), "missing doc"); - } - } - static Version GetJdkVersion () - { - var jdkPath = AndroidSdkResolver.GetJavaSdkPath (); - var releasePath = Path.Combine (jdkPath, "release"); - if (!File.Exists (releasePath)) - return null; - foreach (var line in File.ReadLines (releasePath)) { - const string JavaVersionStart = "JAVA_VERSION=\""; - if (!line.StartsWith (JavaVersionStart, StringComparison.OrdinalIgnoreCase)) - continue; - var value = line.Substring (JavaVersionStart.Length, line.Length - JavaVersionStart.Length - 1); - int last = 0; - for (last = 0; last < value.Length; ++last) { - if (char.IsDigit (value, last) || value [last] == '.') - continue; - break; - } - return Version.Parse (last == value.Length ? value : value.Substring (0, last)); + var path = Path.Combine (Root, bindingBuilder.ProjectDirectory, binding.OutputPath, "UnnamedProject.xml"); + var xml = File.ReadAllText (path); + Assert.IsTrue (xml.Contains ("name to display."), "param `name` documentation not imported!"); } - return null; } [Test] diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs index c69821c5e00..ab69d178fc5 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs @@ -369,12 +369,14 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease) .Select (Path.GetFileName) .OrderBy (f => f) .ToArray (); - CollectionAssert.AreEqual (new [] { + var expectedFiles = new[]{ $"{proj.ProjectName}.dll", $"{proj.ProjectName}.pdb", + $"{proj.ProjectName}.xml", $"{proj.PackageName}.apk", $"{proj.PackageName}-Signed.apk", - }, files); + }; + CollectionAssert.AreEqual (expectedFiles, files, $"Expected: {string.Join (";", expectedFiles)}\n Found: {string.Join (";", files)}"); var assemblyPath = Path.Combine (outputPath, $"{proj.ProjectName}.dll"); FileAssert.Exists (assemblyPath); diff --git a/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.csproj b/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.csproj index 0e59e81a532..d7e1255318f 100644 --- a/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.csproj +++ b/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.csproj @@ -142,6 +142,9 @@ + + + @@ -149,6 +152,7 @@ BuildTestJarFile; _CopyTestJarFiles; + _CreateJavaSourceJar; $(BuildDependsOn) diff --git a/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.targets b/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.targets index 72f6f5c59bf..45a38d3fd96 100644 --- a/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.targets +++ b/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/Xamarin.Android.McwGen-Tests.targets @@ -6,7 +6,18 @@ DestinationFolder="$(OutputPath)" /> + + + + + diff --git a/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/java/com/xamarin/android/DefaultMethodsInterface.java b/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/java/com/xamarin/android/DefaultMethodsInterface.java index 1323f0c5c4b..04f2af75255 100644 --- a/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/java/com/xamarin/android/DefaultMethodsInterface.java +++ b/tests/CodeGen-Binding/Xamarin.Android.McwGen-Tests/java/com/xamarin/android/DefaultMethodsInterface.java @@ -1,5 +1,6 @@ package com.xamarin.android; +/** An interface which contains interface default methods. */ public interface DefaultMethodsInterface { default int foo () { return 0; } From e972c3dcc258af269318e46ac5694b50060c18d1 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Fri, 11 Dec 2020 10:11:02 -0600 Subject: [PATCH 2/9] Fix DotNetBuild tests I fixed what sets `$(DocumentationFile)`: * `$(OutputPath)` always ends with a trailing slash * Check `$(_ComputeFilesToPublishForRuntimeIdentifiers)` so it isn't set on the inner builds in .NET 6 * Fixed typo with `$(_UseLegacyJavadocImport)` --- .../Xamarin/Android/Xamarin.Android.Bindings.Core.targets | 4 ++-- .../Tests/Xamarin.Android.Build.Tests/XASdkTests.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index acb671c4b8a..9911326447f 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -22,8 +22,8 @@ It is shared between "legacy" binding projects and .NET 5 projects. <_GeneratorStampFile>$(IntermediateOutputPath)generator.stamp - - $(OutputPath)\$(AssemblyName).xml + + $(OutputPath)$(AssemblyName).xml $(NoWarn);CS1573;CS1591 diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs index ab69d178fc5..48210a7605f 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/XASdkTests.cs @@ -372,9 +372,9 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease) var expectedFiles = new[]{ $"{proj.ProjectName}.dll", $"{proj.ProjectName}.pdb", - $"{proj.ProjectName}.xml", $"{proj.PackageName}.apk", $"{proj.PackageName}-Signed.apk", + $"{proj.ProjectName}.xml", }; CollectionAssert.AreEqual (expectedFiles, files, $"Expected: {string.Join (";", expectedFiles)}\n Found: {string.Join (";", files)}"); From 587805ae586c1857d8acdedc8ff94bf1cefe5429 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Fri, 11 Dec 2020 14:01:47 -0500 Subject: [PATCH 3/9] [ci] Don't convert Javadoc to Xmldoc for PR builds Context: https://github.com/xamarin/xamarin-android/pull/5253#issuecomment-743232941 When Javadoc-to-Xmldoc conversion was enabled, `make jenkins` took 1h 19min 47sec, up from 34min 45sec (ouch!). Disable Javadoc-to-Xmldoc on PR builds. Hopefully `make jenkins` times will return to normal. --- build-tools/automation/azure-pipelines.yaml | 1 + src/Mono.Android/Mono.Android.csproj | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build-tools/automation/azure-pipelines.yaml b/build-tools/automation/azure-pipelines.yaml index 5c3ebe484f3..d7f052aa869 100644 --- a/build-tools/automation/azure-pipelines.yaml +++ b/build-tools/automation/azure-pipelines.yaml @@ -67,6 +67,7 @@ variables: DotNetNUnitCategories: '& TestCategory != DotNetIgnore & TestCategory != AOT & TestCategory != MkBundle & TestCategory != MonoSymbolicate & TestCategory != PackagesConfig & TestCategory != StaticProject & TestCategory != Debugger' NUnit.NumberOfTestWorkers: 4 GitHub.Token: $(github--pat--vs-mobiletools-engineering-service2) + CONVERT_JAVADOC_TO_XMLDOC: $[ne(variables['Build.DefinitionName'], 'Xamarin.Android-PR')] # Stage and Job "display names" are shortened because they are combined to form the name of the corresponding GitHub check. stages: diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 8b8c905f285..2e196f0cb8d 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -25,8 +25,7 @@ - - True + True From 724cfacbb3982616e97600e02de26fa5c1f80095 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Wed, 16 Dec 2020 22:00:33 -0500 Subject: [PATCH 4/9] [Mono.Android] Emit only summary XML, not full XML Context: https://github.com/xamarin/xamarin-android/pull/5253#issuecomment-747172661 Context: https://github.com/xamarin/java.interop/pull/687#issuecomment-743266123 Context: https://github.com/xamarin/java.interop/pull/687/commits/a65b8aba0d6e8a7f29b38e42397290d3f639708a It looks like only emitting ``, ``, ``, and `` is *much* faster than trying to do full ``. Update the `generator.exe` invocation to use `generator --doc-comment-style=summary`, which will hopefully speed things up. --- Documentation/release-notes/5253.md | 4 ++++ external/Java.Interop | 2 +- src/Mono.Android/Mono.Android.csproj | 7 ++++++- src/Mono.Android/Mono.Android.targets | 2 +- .../Xamarin/Android/Xamarin.Android.Bindings.Core.targets | 2 ++ src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs | 6 +++++- 6 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 Documentation/release-notes/5253.md diff --git a/Documentation/release-notes/5253.md b/Documentation/release-notes/5253.md new file mode 100644 index 00000000000..31967f17c78 --- /dev/null +++ b/Documentation/release-notes/5253.md @@ -0,0 +1,4 @@ +#### Binding library build + + * [GitHub Issue 4789](https://github.com/xamarin/xamarin-android/issues/4789): + Support the `@(JavaSourceJar)` build action on JDK 11 and later. diff --git a/external/Java.Interop b/external/Java.Interop index a65b8aba0d6..d870a082812 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit a65b8aba0d6e8a7f29b38e42397290d3f639708a +Subproject commit d870a082812b367e50425b042fa7e30ac1e392ca diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 2e196f0cb8d..90fe24dc301 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -25,12 +25,17 @@ + + + True + intellisense $(OutputPath)Mono.Android.xml - CS1573;CS1591 + CS1572;CS1573;CS1574;CS1587;CS1591; diff --git a/src/Mono.Android/Mono.Android.targets b/src/Mono.Android/Mono.Android.targets index 13343a093f3..98364ae33dd 100644 --- a/src/Mono.Android/Mono.Android.targets +++ b/src/Mono.Android/Mono.Android.targets @@ -157,7 +157,7 @@ <_TypeMap>--type-map-report=$(IntermediateOutputPath)mcw\type-mapping.txt <_Api>$(IntermediateOutputPath)mcw\api.xml <_Dirs>--enumdir=$(IntermediateOutputPath)mcw - <_WithJavadocXml Condition=" '$(IncludeAndroidJavadoc)' == 'True' ">"--with-javadoc-xml=$(_AndroidJavadocXml)" + <_WithJavadocXml Condition=" '$(IncludeAndroidJavadoc)' == 'True' ">--doc-comment-verbosity=$(AndroidJavadocVerbosity) "--with-javadoc-xml=$(_AndroidJavadocXml)" <_FullIntermediateOutputPath>$([System.IO.Path]::GetFullPath('$(IntermediateOutputPath)')) <_LangFeatures>--lang-features=nullable-reference-types <_LangFeatures Condition="$(AndroidApiLevel) >= 30">$(_LangFeatures),default-interface-methods,nested-interface-types,interface-constants diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index 9911326447f..a2bc0142ad0 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -18,6 +18,7 @@ It is shared between "legacy" binding projects and .NET 5 projects. false $(IntermediateOutputPath)generated\ + intellisense $(IntermediateOutputPath)api.xml <_GeneratorStampFile>$(IntermediateOutputPath)generator.stamp @@ -74,6 +75,7 @@ It is shared between "legacy" binding projects and .NET 5 projects. ApiXmlInput="$(ApiOutputFile)" AnnotationsZipFiles="@(AnnotationsZip)" AssemblyName="$(AssemblyName)" + JavadocVerbosity="$(AndroidJavadocVerbosity)" JavadocXml="@(_JavadocXml)" TransformFiles="@(TransformFile)" ReferencedManagedLibraries="@(ReferencePath);@(ReferenceDependencyPaths)" diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs index 213205f14c2..e73cc96debc 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Generator.cs @@ -53,6 +53,7 @@ public class BindingsGenerator : AndroidDotnetToolTask public ITaskItem[] AnnotationsZipFiles { get; set; } public ITaskItem[] JavadocXml { get; set; } + public string JavadocVerbosity { get; set; } private List> transform_files = new List> (); @@ -169,9 +170,12 @@ protected override string GenerateCommandLineCommands () if (EnableInterfaceMembersPreview && SupportsCSharp8) WriteLine (sw, "--lang-features=interface-constants,default-interface-methods"); + if (!string.IsNullOrEmpty (JavadocVerbosity)) + WriteLine (sw, $"\"--doc-comment-verbosity={JavadocVerbosity}\""); + if (JavadocXml != null) { foreach (var xml in JavadocXml) { - WriteLine (sw, $"--with-javadoc-xml=\"{Path.GetFullPath (xml.ItemSpec)}\""); + WriteLine (sw, $"\"--with-javadoc-xml={Path.GetFullPath (xml.ItemSpec)}\""); } } } From 3d29733175db0076076ff3ba397f65ff8a615b07 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Thu, 17 Dec 2020 18:27:50 -0500 Subject: [PATCH 5/9] Address feedback Bump to jonpryor/Java.Interop/jonp-generator-javadoc-xml@32d469bb, which addresses some feedback on the Java.Interop side. Document the new `$(AndroidJavadocVerbosity)` property. Document the existing `@(JavaSourceJar)` build action. Append to `$(NoWarn)` instead of *replacing* it in `src/Mono.Android`. Avoid `**\*-source?.jar`, as that doesn't mean what I thought it meant. Instead, add/use `$(_DefaultJavaSourceJarPattern)`, which explicitly specifies both `*-source.jar` and `*-sources.jar`. Re-introduce the "don't build XML docs on PR builds" behavior. --- .../guides/building-apps/build-items.md | 31 +++++++++++++++++++ .../guides/building-apps/build-properties.md | 27 ++++++++++++++++ external/Java.Interop | 2 +- src/Mono.Android/Mono.Android.csproj | 6 +--- .../Sdk/AutoImport.props | 8 +++-- 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 64d4a1adc1f..61aa1795474 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -298,6 +298,37 @@ such as ``: ``` +## JavaSourceJar + +In a Xamarin.Android binding project, the **JavaSourceJar** build action +is used on `.jar` files which contain *Java source code*, which contains +[Javadoc documentation comments](https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html). + +Prior to Xamarin.Android 11.3, the Javadoc would be converted into HTML +via the `javadoc` utility during build time, and later turned into +XML documentation. + +Starting with Xamarin.Android 11.3, Javadoc will instead be converted into +[C# XML Documentation Comments](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc) +within the generated binding source code. + +[`$(AndroidJavadocVerbosity)`](~/android/deploy-test/building-apps/build-properties.md#androidjavadocverbosity) +controls how "verbose" or "complete" the imported Javadoc is. + +The following MSBuild metadata is supported: + +* `%(CopyrightFile)`: A path to a file that contains copyright + information for the Javadoc contents, which will be appended to + all imported documentation. + +* `%(UrlPrefix)`: A URL prefix to support linking to online + documentation within imported documentation. + +* `%(UrlStyle)`: The "style" of URLs to generate when linking to + online documentation. Only one style is currently supported: + `developer.android.com/reference@2020-Nov`. + + ## LibraryProjectZip In a Xamarin.Android binding project, the **LibraryProjectZip** build diff --git a/Documentation/guides/building-apps/build-properties.md b/Documentation/guides/building-apps/build-properties.md index 6b3e75ff7ce..bc1008bb405 100644 --- a/Documentation/guides/building-apps/build-properties.md +++ b/Documentation/guides/building-apps/build-properties.md @@ -623,6 +623,33 @@ APK root directory. The format of the path is `lib\ARCH\wrap.sh` where + `x86_64` + `x86` +## AndroidJavadocVerbosity + +Specifies how "verbose" +[C# XML Documentation Comments](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc) +should be when importing Javadoc documentation within binding projects. + +Requires use of the +[`@(JavaSourceJar)`](~/android/deploy-test/building-apps/build-items.md#javasourcejar) +build action. + +This is an enum-style property, with possible values of `full` or +`intellisense`: + + * `intellisense`: Only emit the XML comments: + [`](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc#exception), + [``](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc#param), + [``](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc#returns), + [``](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc#summary). + * `full`: Emit `intellisense` elements, as well as + [``](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc#remarks), + [``](https://docs.microsoft.com/en-us/dotnet/csharp/codedoc#seealso), + and anything else that's supportable. + +The default value is `intellisense`. + +Added in Xamarin.Android 11.3. + ## AndroidKeyStore A boolean value which indicates whether diff --git a/external/Java.Interop b/external/Java.Interop index d870a082812..32d469bbf98 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit d870a082812b367e50425b042fa7e30ac1e392ca +Subproject commit 32d469bbf98451e847b2101347abae4cc4774999 diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 90fe24dc301..46f417b531e 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -25,17 +25,13 @@ - - - True intellisense $(OutputPath)Mono.Android.xml - CS1572;CS1573;CS1574;CS1587;CS1591; + $(NoWarn);CS1572;CS1573;CS1574;CS1587;CS1591; diff --git a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props index 47258a0d831..8ceb6424d9d 100644 --- a/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props +++ b/src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/Sdk/AutoImport.props @@ -16,6 +16,10 @@ https://github.com/dotnet/designs/blob/4703666296f5e59964961464c25807c727282cae/ --> + + <_DefaultJavaSourceJarPattern>**\*-source.jar;**\*-sources.jar;**\*-src.jar + + @@ -33,10 +37,10 @@ https://github.com/dotnet/designs/blob/4703666296f5e59964961464c25807c727282cae/ - + - + From ff5f895f3d4bfaf7f02bb94034e01455fa565d0e Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Mon, 4 Jan 2021 14:02:10 -0500 Subject: [PATCH 6/9] Bump to xamarin/Java.Interop/master@7574f166 Changes: https://github.com/xamarin/java.interop/compare/2f62ffd4367870802f146c7957a94839daf1b86d...7574f166008bb45c0df97315aae7907ac25f8602 * xamarin/Java.Interop@7574f166: [generator] Add `generator --with-javadoc-xml=FILE` support. (#687) * xamarin/Java.Interop@7d197f17: Refactor Crc64 type (#769) * xamarin/Java.Interop@876442f4: [generator] Fix MSBuild warning/error format for Visual Studio (#765) * xamarin/Java.Interop@3f6cf72b: [.Localization, .Cecil, .Diagnostics, .Generator] $(Nullable)=enable (#746) https://github.com/xamarin/java.interop/pull/687 was merged. --- .gitmodules | 4 ++-- external/Java.Interop | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index ad35fb0808c..90e5d57bc21 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,8 +12,8 @@ branch = master [submodule "external/Java.Interop"] path = external/Java.Interop - url = https://github.com/jonpryor/java.interop.git - branch = jonp-generator-javadoc-xml + url = https://github.com/xamarin/java.interop.git + branch = master [submodule "external/lz4"] path = external/lz4 url = https://github.com/lz4/lz4.git diff --git a/external/Java.Interop b/external/Java.Interop index 32d469bbf98..7574f166008 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 32d469bbf98451e847b2101347abae4cc4774999 +Subproject commit 7574f166008bb45c0df97315aae7907ac25f8602 From 2ca9f4cd22763a6d3a6c46c2df51979974cfa5e4 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Mon, 4 Jan 2021 19:28:57 -0500 Subject: [PATCH 7/9] [Mono.Android, Xamarin.Android.Tools.JavadocImporter] Fix build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Context: https://github.com/xamarin/java.interop/commit/7d197f17a0f9d73854522d6e1d68deafbcdbcaf6 Context: https://github.com/xamarin/xamarin-android/pull/5452 xamarin/java.interop@7d197f17 introduced build breakage: …/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/Crc64.cs(58,16): error CS0117: 'Crc64Helper' does not contain a definition for 'HashCore' …/xamarin-android/external/Java.Interop/src/Java.Interop.Tools.TypeNameMappings/Java.Interop.Tools.TypeNameMappings/JavaNativeTypeManager.cs(648,27): error CS0117: 'Crc64Helper' does not contain a definition for 'Compute' PR #5452 has the fix. Include the build fix so that PR #5253 can build. --- src/Mono.Android/Mono.Android.csproj | 3 +++ .../Xamarin.Android.Tools.JavadocImporter.csproj | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Mono.Android/Mono.Android.csproj b/src/Mono.Android/Mono.Android.csproj index 46f417b531e..0b402b4fd5f 100644 --- a/src/Mono.Android/Mono.Android.csproj +++ b/src/Mono.Android/Mono.Android.csproj @@ -106,6 +106,9 @@ Crc64.cs + + Crc64Helper.cs + Crc64.Table.cs diff --git a/src/Xamarin.Android.Tools.JavadocImporter/Xamarin.Android.Tools.JavadocImporter.csproj b/src/Xamarin.Android.Tools.JavadocImporter/Xamarin.Android.Tools.JavadocImporter.csproj index d68922b4dcf..6de5ae4ec37 100644 --- a/src/Xamarin.Android.Tools.JavadocImporter/Xamarin.Android.Tools.JavadocImporter.csproj +++ b/src/Xamarin.Android.Tools.JavadocImporter/Xamarin.Android.Tools.JavadocImporter.csproj @@ -26,6 +26,9 @@ Crc64.cs + + Crc64Helper.cs + Crc64.Table.cs From 4d937fc6228719522a3dfa46acd1554a0c0b6872 Mon Sep 17 00:00:00 2001 From: Jonathan Pryor Date: Tue, 5 Jan 2021 20:19:50 -0500 Subject: [PATCH 8/9] Rethink ordering Context: https://github.com/xamarin/java.interop/issues/767 Context: https://github.com/xamarin/xamarin-android/pull/5253#discussion_r551831606 xamarin/java.interop#767 suggests updating `generator` to use Javadoc output to determine parameter names. However, we don't need to do that, as `class-parse` *already* has (partial) support for that. Split the `` invocation out into a new `_ExtractJavadocsFromJavaSourceJars` target invocation, and give it a "proper" output item group. This allows it to be executed in an incremental manner, which wasn't previously the case. Additionally, the previous `` invocation "minimized" the number of Javadoc XML output files based on the "unique" values of `%(CopyrightFile)`/etc. Thus, if you had multiple `@(JavaSourceJar)`s with the same (or no) `%(CopyrightFile)` file, they'd all be present in the same output XML. While this was "nice" in that it reduced the number of files running around, it complicated coming up with a separate item group for incremental build purposes. Remove the "nicety" and go for "simplicity": one Javadoc XML per `@(JavaSourceJar)` file. Period. Add a `$(AndroidJavaSourceUtilsJar)` MSBuild property which controls where `java-source-utils.jar` is present. This is consistent with other tasks. However, *don't* allow `class-parse` to use `java-source-utils` output, as that doesn't actually work yet. Doh. --- ...amarin.Android.Bindings.ClassParse.targets | 40 +++++++++++++++++++ .../Xamarin.Android.Bindings.Core.targets | 18 +-------- .../Tasks/JavaSourceUtils.cs | 10 +---- .../Xamarin.Android.Bindings.targets | 7 ++++ .../Xamarin.Android.Common.targets | 6 +++ 5 files changed, 56 insertions(+), 25 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets index 9db19f1678d..7d61a578409 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets @@ -14,9 +14,14 @@ This file is only used by binding projects. + + <_AndroidDocumentationPath Include="@(JavaDocIndex->'%(RootDir)\%(Directory)')" /> <_AndroidDocumentationPath Include="$(JavaDocPaths)" /> <_AndroidDocumentationPath Include="$(Java7DocPaths)" /> @@ -43,4 +48,39 @@ This file is only used by binding projects. /> + + + + + + <_JavaSourceJavadocXml Include="@(_JavaSourceJarHashes->'$(IntermediateOutputPath)javadoc-%(Filename)-%(Hash).xml')" /> + + + + + + + + + + diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index 3b05f3e5d42..696536dbd59 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -49,22 +49,6 @@ It is shared between "legacy" binding projects and .NET 5 projects. - - - - "JSU"; [Required] - public string MonoAndroidToolsDirectory { get; set; } + public string JavaSourceUtilsJar { get; set; } [Required] public string JavaSdkDirectory { get; set; } - [Required] - public ITaskItem OutputDirectory { get; set; } - [Required] public ITaskItem[] InputFiles { get; set; } @@ -38,7 +35,6 @@ public class JavaSourceUtils : AndroidToolTask public string JavaMaximumHeapSize { get; set; } - [Output] public ITaskItem OutputJavadocXml { get; set; } string responseFilePath; @@ -58,8 +54,6 @@ public override bool RunTask () if (Log.HasLoggedErrors) return false; - OutputJavadocXml = new TaskItem (Path.Combine (OutputDirectory.ItemSpec, GetOutputFileName (InputFiles)) + ".xml"); - try { return base.RunTask (); } @@ -90,7 +84,7 @@ protected override string GenerateCommandLineCommands () } // Arguments sent to java.exe - cmd.AppendSwitchIfNotNull ("-jar ", Path.Combine (MonoAndroidToolsDirectory, "java-source-utils.jar")); + cmd.AppendSwitchIfNotNull ("-jar ", JavaSourceUtilsJar); cmd.AppendSwitch ($"@{responseFilePath}"); diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets index fe895d11e03..040a1d53f76 100755 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Bindings.targets @@ -19,6 +19,7 @@ Copyright (C) 2012 Xamarin Inc. All rights reserved. --> + diff --git a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets index 41fd8284eef..3f3b8b39c89 100644 --- a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets +++ b/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets @@ -641,6 +641,12 @@ because xbuild doesn't support framework reference assemblies. /> + + + + Date: Wed, 6 Jan 2021 09:24:36 -0500 Subject: [PATCH 9/9] Mention when JavaSourceJar metadata is supported. --- Documentation/guides/building-apps/build-items.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/guides/building-apps/build-items.md b/Documentation/guides/building-apps/build-items.md index 61aa1795474..0f81bf9e1ef 100644 --- a/Documentation/guides/building-apps/build-items.md +++ b/Documentation/guides/building-apps/build-items.md @@ -315,7 +315,7 @@ within the generated binding source code. [`$(AndroidJavadocVerbosity)`](~/android/deploy-test/building-apps/build-properties.md#androidjavadocverbosity) controls how "verbose" or "complete" the imported Javadoc is. -The following MSBuild metadata is supported: +Starting in Xamarin.Android 11.3, the following MSBuild metadata is supported: * `%(CopyrightFile)`: A path to a file that contains copyright information for the Javadoc contents, which will be appended to