Skip to content

Commit

Permalink
[Xamarin.Android.Tools.Bytecode] Extend api xml doc type detection (#943
Browse files Browse the repository at this point in the history
)

Context: dotnet/android#6662

The [`@(JavaSourceJar)`][0] Build action supports the following
item metadata:

	<JavaSourceJar Include="javasourcejartest-sources.jar" >
	  <CopyrightFile>$(MSBuildThisFileDirectory)javadoc-copyright.xml</CopyrightFile>
	  <UrlPrefix>https://developer.android.com/reference</UrlPrefix>
	  <UrlStyle>developer.android.com/reference@2020-Nov</UrlStyle>
	  <DocRootUrl>https://developer.android.com</DocRootUrl>
	</JavaSourceJar>

`@(JavaSourceJar)` is used by the Xamarin.Android `<JavaSourceUtils/>`
task, which uses all of the item metadata as various option values to
`java-source-utils.jar --output-javadoc` (7574f16), resulting in
"Javadoc XML", which is subsequently provided to the `<ClassParse/>`
MSBuild task, which passes the "Javadoc XML" as a
`class-parse --docspath=PATH` option value.

`class-parse.exe --docspath=PATH` (eventually) uses
`JavaMethodParameterNameProvider.GetDocletType()` to determine the
file format of `PATH`, and `GetDocletType()` reads the first 500
bytes of the file to determine if `PATH` is `JavaDocletType._ApiXml`
(`<api/>` XML, as produced by `class-parse.exe` & others) or
`JavaDocletType.JavaApiParameterNamesXml` (which *isn't* xml, and is
produced by `java-source-utils.jar --output-params`).

If a `%(JavaSourceJar.CopyrightFile)` file is "large" (> 500 bytes),
then `GetDocletType()` won't detect the "Javadoc XML" file as
`JavaDocletType._ApiXml`, but instead as `JavaDocletType.DroidDoc`
(the default!), which results in (bizarre!) build errors:

	Task "ClassParse"
	  Task Parameter:ToolPath=C:\Users\cloudtest\android-toolchain\dotnet\packs\Microsoft.Android.Sdk.Windows\31.0.200-ci.pr.gh6662.38\tools
	  Task Parameter:OutputFile=obj\Debug\api.xml.class-parse
	  Task Parameter:SourceJars=javasourcejartest.jar
	  Task Parameter:
	      DocumentationPaths=
	          obj\Debug\javadoc-javasourcejartest-sources-C93909CC4CF9CB39.xml
	                  CopyrightFile=…\TestRelease\01-25_05.25.10\temp\JavaSourceJar\javadoc-copyright.xml
	                  DocRootUrl=https://developer.android.com
	                  Hash=C93909CC4CF9CB39
	                  OriginalItemSpec=javasourcejartest-sources.jar
	                  UrlPrefix=https://developer.android.com/reference
	                  UrlStyle=developer.android.com/reference@2020-Nov
	  Using: dotnet C:\Users\cloudtest\android-toolchain\dotnet\packs\Microsoft.Android.Sdk.Windows\31.0.200-ci.pr.gh6662.38\tools\class-parse.dll
	  [class-parse] response file: obj\Debug\class-parse.rsp
	  --o="obj\Debug\api.xml.class-parse"
	  --docspath="obj\Debug\javadoc-javasourcejartest-sources-C93909CC4CF9CB39.xml"
	  "javasourcejartest.jar"
	  dotnet C:\Users\cloudtest\android-toolchain\dotnet\packs\Microsoft.Android.Sdk.Windows\31.0.200-ci.pr.gh6662.38\tools\class-parse.dll @obj\Debug\class-parse.rsp
	  Unhandled exception. System.Exception: Directory 'obj\Debug\javadoc-javasourcejartest-sources-C93909CC4CF9CB39.xml' does not exist
	     at Xamarin.Android.Tools.Bytecode.AndroidDocScraper..ctor(String dir, String patternHead, String resetPatternHead, String parameterPairSplitter, Boolean continuousParamLines, String openMethod, String paramSep, String closeMethod, String postCloseMethodParens)
	     at Xamarin.Android.Tools.Bytecode.AndroidDocScraper..ctor(String dir, String patternHead, String resetPatternHead, String parameterPairSplitter, Boolean continuousParamLines)
	     at Xamarin.Android.Tools.Bytecode.DroidDocScraper..ctor(String dir)
	     at Xamarin.Android.Tools.Bytecode.ClassPath.CreateDocScraper(String src)
	     at Xamarin.Android.Tools.Bytecode.ClassPath.FixupParametersFromDocs(XElement api, String path)
	     at Xamarin.Android.Tools.Bytecode.ClassPath.FixupParametersFromDocs(XElement api)
	     at Xamarin.Android.Tools.Bytecode.ClassPath.ToXElement()
	     at Xamarin.Android.Tools.Bytecode.ClassPath.SaveXmlDescription(TextWriter textWriter)
	     at Xamarin.Android.Tools.App.Main(String[] args)

Fix the `JavaDocletType._ApiXml` doc type detection in such cases by
also checking for the `<javadoc-metadata>` element that is created by
`java-source-utils.jar --output-javadoc`.

[0]: https://docs.microsoft.com/en-us/xamarin/android/deploy-test/building-apps/build-items#javasourcejar
  • Loading branch information
pjcollins authored Jan 25, 2022
1 parent 88d6093 commit 32635fd
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,8 @@ public static JavaDocletType GetDocletType (string path)
rawXML = new string (buf, 0, len).Trim ();
}
if (rawXML.IndexOf ("<api", StringComparison.Ordinal) >= 0 &&
rawXML.IndexOf ("<package", StringComparison.Ordinal) >= 0)
(rawXML.IndexOf ("<package", StringComparison.Ordinal) >= 0 ||
rawXML.IndexOf ("<javadoc-metadata", StringComparison.Ordinal) >= 0))
kind = JavaDocletType._ApiXml;
else if (rawXML.StartsWith ("package", StringComparison.Ordinal) ||
rawXML.StartsWith (";", StringComparison.Ordinal)) {
Expand Down

0 comments on commit 32635fd

Please sign in to comment.