Skip to content

generator should pull parameter names from Javadoc #767

New issue

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

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

Already on GitHub? # to your account

Closed
jonpryor opened this issue Dec 18, 2020 · 1 comment · Fixed by dotnet/android#5468
Closed

generator should pull parameter names from Javadoc #767

jonpryor opened this issue Dec 18, 2020 · 1 comment · Fixed by dotnet/android#5468
Labels
enhancement Proposed change to current functionality generator Issues binding a Java library (generator, class-parse, etc.)

Comments

@jonpryor
Copy link
Member

Related? PR #687.

Parameter names remains an ongoing concern. "Best" is if the Java code is built with javac -parameters, which allows class-parse to extract parameter names, and everything is good.

Unfortunately, that still appears to be a rarity in the Java world.

Lacking javac -parameters, how should bindings get decent parameter names? A "reasonable" answer is to integrate @(JavaSourceJar) support, which with PR #687 and dotnet/android#5253 will parse @(JavaSourceJar) with java-source-utils.jar (69e1b80) to extract Javadoc and parameter names.

However, PR #687 is focused on parsing the Javadoc comments and translating them into C# XML Documentation Comments.

We should also look into using generator --with-javadoc-xml=FILE to determine parameter names as well.

Then there's the "priority" question: I think it would be most "sensible" and documentable if the last "source of truth" for parameter names was used in the bindings:

  1. class-parse output.
  2. java-source-utils.jar output
  3. Metadata.xml updates

This would allow Metadata.xml to always override.

@jpobst jpobst added enhancement Proposed change to current functionality generator Issues binding a Java library (generator, class-parse, etc.) labels Dec 18, 2020
@jonpryor
Copy link
Member Author

jonpryor commented Jan 5, 2021

On further consideration, I don't think this requires any changes to generator.

Instead, we should update the _ExportJarToXml target so that the output of java-source-utils.jar is provided to ClassParse.DocumentationPaths. This will cause java-source-utils.jar output to be treated identically to Javadoc HTML input files regarding parameter names.

jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jan 6, 2021
Context: dotnet/java-interop#767
Context: dotnet#5253 (comment)

dotnet/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 `<JavaSourceUtils/>` 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 `<JavaSourceUtils/>` 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.
jonpryor added a commit to jonpryor/java.interop that referenced this issue Jan 6, 2021
Context: dotnet#767
Context: https://github.com/xamarin/xamarin-android/blob/a7413a2389886082c3d3422c50a7e6cc84f43d8f/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets#L23

Commit 69e1b80 added `java-source-utils.jar`, which can parse Java
source code to extract parameter names, storing them into a
"`class-parse`-like XML file".

A benefit to a "`class-parse`-like XML file" is that it should be
possible to use this same file with `class-parse --docspath`,
overriding parameter names present in Java bytecode (which typically
*isn't* present, as `javac -parameters` is rarely used).

Unfortunately, this doesn't work: if you attempt to use
`java-source-utils.jar` output w/ `class-parse --docspath`, it fails:

	System.Exception: Directory 'example.xml' does not exist
	  at Xamarin.Android.Tools.Bytecode.AndroidDocScraper..ctor (System.String dir, System.String patternHead, System.String resetPatternHead, System.String parameterPairSplitter, System.Boolean continuousParamLines, System.String openMethod, System.String paramSep, System.String closeMethod, System.String postCloseMethodParens) [0x00093] in <e7fad12ab9c24ce08dac8732f18e1d85>:0
	  at Xamarin.Android.Tools.Bytecode.AndroidDocScraper..ctor (System.String dir, System.String patternHead, System.String resetPatternHead, System.String parameterPairSplitter, System.Boolean continuousParamLines) [0x00000] in <e7fad12ab9c24ce08dac8732f18e1d85>:0
	  at Xamarin.Android.Tools.Bytecode.DroidDocScraper..ctor (System.String dir) [0x00000] in <e7fad12ab9c24ce08dac8732f18e1d85>:0
	  at Xamarin.Android.Tools.Bytecode.ClassPath.CreateDocScraper (System.String src) [0x00037] in <e7fad12ab9c24ce08dac8732f18e1d85>:0

The problem is that we shouldn't be creating a `DroidDocScraper`
for `java-source-utils.jar` output, it should be creating a
`ApiXmlDocScraper`!

We're creating the wrong `*Scraper` type because
`JavaMethodParameterNameProvider.GetDocletType()` doesn't detect
`java-source-utils.jar` output as being `JavaDocletType._ApiXml`;
instead, it treats it as the default of `JavaDocletType.DroidDoc`.

`JavaMethodParameterNameProvider.GetDocletType()` doesn't detect
`java-source-utils.jar` output as being `JavaDocletType._ApiXml`,
because it requires that the XML contain:

	<api>

while `java-source-utils.jar` instead emits:

	<api api-source="java-source-utils">

Relax `JavaMethodParameterNameProvider.GetDocletType()` to instead
check for `<api`.  This allows `class-parse` to use
`java-source-utils.jar` output for parameter names.
jonpryor added a commit that referenced this issue Jan 6, 2021
Context: #767
Context: https://github.com/xamarin/xamarin-android/blob/a7413a2389886082c3d3422c50a7e6cc84f43d8f/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.ClassParse.targets#L23

Commit 69e1b80 added `java-source-utils.jar`, which can parse Java
source code to extract parameter names, storing them into a
"`class-parse`-like XML file".

A benefit to a "`class-parse`-like XML file" is that it should be
possible to use this same file with `class-parse --docspath`,
overriding parameter names present in Java bytecode (which typically
*isn't* present, as `javac -parameters` is rarely used).

Unfortunately, this doesn't work: if you attempt to use
`java-source-utils.jar` output w/ `class-parse --docspath`, it fails:

	System.Exception: Directory 'example.xml' does not exist
	  at Xamarin.Android.Tools.Bytecode.AndroidDocScraper..ctor (System.String dir, System.String patternHead, System.String resetPatternHead, System.String parameterPairSplitter, System.Boolean continuousParamLines, System.String openMethod, System.String paramSep, System.String closeMethod, System.String postCloseMethodParens) [0x00093] in <e7fad12ab9c24ce08dac8732f18e1d85>:0
	  at Xamarin.Android.Tools.Bytecode.AndroidDocScraper..ctor (System.String dir, System.String patternHead, System.String resetPatternHead, System.String parameterPairSplitter, System.Boolean continuousParamLines) [0x00000] in <e7fad12ab9c24ce08dac8732f18e1d85>:0
	  at Xamarin.Android.Tools.Bytecode.DroidDocScraper..ctor (System.String dir) [0x00000] in <e7fad12ab9c24ce08dac8732f18e1d85>:0
	  at Xamarin.Android.Tools.Bytecode.ClassPath.CreateDocScraper (System.String src) [0x00037] in <e7fad12ab9c24ce08dac8732f18e1d85>:0

The problem is that we shouldn't be creating a `DroidDocScraper`
for `java-source-utils.jar` output, it should be creating a
`ApiXmlDocScraper`!

We're creating the wrong `*Scraper` type because
`JavaMethodParameterNameProvider.GetDocletType()` doesn't detect
`java-source-utils.jar` output as being `JavaDocletType._ApiXml`;
instead, it treats it as the default of `JavaDocletType.DroidDoc`.

`JavaMethodParameterNameProvider.GetDocletType()` doesn't detect
`java-source-utils.jar` output as being `JavaDocletType._ApiXml`,
because it requires that the XML contain:

	<api>

while `java-source-utils.jar` instead emits:

	<api api-source="java-source-utils">

Relax `JavaMethodParameterNameProvider.GetDocletType()` to instead
check for `<api`.  This allows `class-parse` to use
`java-source-utils.jar` output for parameter names.
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jan 6, 2021
Fixes: dotnet/java-interop#767

Changes: dotnet/java-interop@7574f16...fdc200c

  * dotnet/java-interop@fdc200cc: [Xamarin.Android.Tools.Bytecode] Relax _ApiXml check (dotnet#772)
  * dotnet/java-interop@f1b93653: [generator] Change generated code to not emit CA1305 warning. (dotnet#771)
  * dotnet/java-interop@2244407d: [generator] Ensure DIM from assembly refs are correctly marked (dotnet#770)
  * dotnet/java-interop@da73d6a5: [Java.Interop] Prevent premature collection w/ JniInstance* (dotnet#768)

Commit a7413a2 added support for invoking `java-source-utils.jar`
on `@(JavaSourceJar)` to extract Javadoc comments and translate them
into C# XML Documentation Comments.

What this can *also* do is provide correct parameter names.
As of commit a7413a2, the `BindingBuildTest.JavaSourceJar()`
integration test would emit the warning:

	obj/Debug/generated/src/Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest.cs(75,20):
	warning CS1572: XML comment has a param tag for 'name', but there is no parameter by that name

Commit dotnet/java-interop@fdc200cc allows `java-source-utils.jar`
output to be used with `class-parse`, allowing
`@(_JavaSourceJavadocXml)` files -- the output of
`java-source-utils.jar` -- to be included in
`@(_AndroidDocumentationPath)`.

This allows `@(JavaSourceJar)` files to provide parameter names
within bindings, removing the CS1572 warning, and making for
better overall bindings.
jonpryor added a commit to jonpryor/xamarin-android that referenced this issue Jan 6, 2021
Fixes: dotnet/java-interop#767

Changes: dotnet/java-interop@7574f16...fdc200c

  * dotnet/java-interop@fdc200cc: [Xamarin.Android.Tools.Bytecode] Relax _ApiXml check (dotnet#772)
  * dotnet/java-interop@f1b93653: [generator] Change generated code to not emit CA1305 warning. (dotnet#771)
  * dotnet/java-interop@2244407d: [generator] Ensure DIM from assembly refs are correctly marked (dotnet#770)
  * dotnet/java-interop@da73d6a5: [Java.Interop] Prevent premature collection w/ JniInstance* (dotnet#768)

Commit a7413a2 added support for invoking `java-source-utils.jar`
on `@(JavaSourceJar)` to extract Javadoc comments and translate them
into C# XML Documentation Comments.

What this can *also* do is provide correct parameter names.
As of commit a7413a2, the `BindingBuildTest.JavaSourceJar()`
integration test would emit the warning:

	obj/Debug/generated/src/Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest.cs(75,20):
	warning CS1572: XML comment has a param tag for 'name', but there is no parameter by that name

Commit dotnet/java-interop@fdc200cc allows `java-source-utils.jar`
output to be used with `class-parse`, allowing
`@(_JavaSourceJavadocXml)` files -- the output of
`java-source-utils.jar` -- to be included in
`@(_AndroidDocumentationPath)`.

This allows `@(JavaSourceJar)` files to provide parameter names
within bindings, removing the CS1572 warning, and making for
better overall bindings.
jonpryor added a commit to dotnet/android that referenced this issue Jan 7, 2021
Fixes: dotnet/java-interop#767

Changes: dotnet/java-interop@7574f16...fdc200c

  * dotnet/java-interop@fdc200cc: [Xamarin.Android.Tools.Bytecode] Relax _ApiXml check (#772)
  * dotnet/java-interop@f1b93653: [generator] Change generated code to not emit CA1305 warning. (#771)
  * dotnet/java-interop@2244407d: [generator] Ensure DIM from assembly refs are correctly marked (#770)
  * dotnet/java-interop@da73d6a5: [Java.Interop] Prevent premature collection w/ JniInstance* (#768)

Commit a7413a2 added support for invoking `java-source-utils.jar`
on `@(JavaSourceJar)` to extract Javadoc comments and translate them
into C# XML Documentation Comments.

What this can *also* do is provide correct parameter names.
As of commit a7413a2, the `BindingBuildTest.JavaSourceJar()`
integration test would emit the warning:

	obj/Debug/generated/src/Com.Xamarin.Android.Test.Msbuildtest.JavaSourceJarTest.cs(75,20):
	warning CS1572: XML comment has a param tag for 'name', but there is no parameter by that name

Commit dotnet/java-interop@fdc200cc allows `java-source-utils.jar`
output to be used with `class-parse`, allowing
`@(_JavaSourceJavadocXml)` files -- the output of
`java-source-utils.jar` -- to be included in
`@(_AndroidDocumentationPath)`.

This allows `@(JavaSourceJar)` files to provide parameter names
within bindings, removing the CS1572 warning, and making for
better overall bindings.

We can see the benefits of this change in
`tests/CodeGen-Binding/Xamarin.Android.JcwGen-Tests/BindingTests.cs`,
which required changes because the parameter names in the Java
`DataListener.onDataReceived()` method could now be determined;
previously they couldn't, resulting in the `P0`/`P1`/etc. names.
With the provision of `@(JavaSourceJar)` -- a7413a2 updated
`Xamarin.Android.McwGen-Tests.csproj` to have `@(JavaSourceJar)` --
the parameter names can now be determined, improving the binding.
@github-actions github-actions bot locked and limited conversation to collaborators Apr 12, 2024
# for free to subscribe to this conversation on GitHub. Already have an account? #.
Labels
enhancement Proposed change to current functionality generator Issues binding a Java library (generator, class-parse, etc.)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants