8000 Types of extracted default args are unambiguous in doclets after all. Get them right in extracted formal param lists. Fix #56. by erikrose · Pull Request #57 · pyodide/sphinx-js · GitHub
[go: up one dir, main page]

Skip to content

Types of extracted default args are unambiguous in doclets after all. Get them right in extracted formal param lists. Fix #56. #57

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 20, 2018

Conversation

erikrose
Copy link
Contributor
@erikrose erikrose commented Apr 4, 2018

JSDoc doesn't extract compound default literals like objects or Arrays yet, so we don't test those.

@flozz Would you mind reviewing this? Thank you!

… Get them right in extracted formal param lists. Fix #56.

JSDoc doesn't extract compound default literals like objects or Arrays yet, so we don't test those.
@flozz
Copy link
Contributor
flozz commented Apr 5, 2018

Hi,

I made some tests, and there still be some inconsistencies between the values JSDoc finds from the js code (when using es6 syntax) and values manually documented in doclets. Also there is issue to document "complex" types like objects, arrays, functions,...

Sphinx .rst

.. js:autoclass:: Foobar
   :members: simple_type_implicite,
             simple_type_explicite,
             simple_type_explicite2,
             array_object_function_implicite,
             array_object_function_explicite,
             constants_implicite,
             constants_explicite

Example .js file

https://gist.github.com/flozz/0cb94dbe6e79d43ba31c5727684d24fe

Tests with simple types

/**
 * If we let jsdoc extracting the default values (es6 syntax), the
 * result is ok for simple types (number, string, boolean and null)
 *
 * @param {*} a
 * @param {number} [b]
 * @param {boolean} [c]
 * @param {string} [d]
 */
simple_type_implicite(a, b=42, c=false, d="false") {
}

capture d ecran de 2018-04-05 10-33-43

/**
 * If we document explicitely values, it does not works as expected:
 * If something looks like a boolean or a number, it is "casted", so we
 * cannot have a ``"42"`` or a ``"false"`` string
 *
 * @param {*} a
 * @param {number} [b=42]
 * @param {boolean} [c=false]
 * @param {string} [d=false]
 */
simple_type_explicite(a, b=42, c=false, d="false") {
}

capture d ecran de 2018-04-05 10-33-53

/**
 * An other exemple with explicite documentation
 *
 * @param [a=42]
 * @param [b="42"]
 * @param [c=false]
 * @param [d="false"]
 */
simple_type_explicite2(a, b, c, d) {
}

capture d ecran de 2018-04-05 10-34-03

Tests with more complex types

/**
 * More complex types are not documented automatically...
 *
 * @param [obj]
 * @param [arr]
 * @param [fn]
 */
array_object_function_implicite(obj={}, arr=[], fn=function(){}) {
}

capture d ecran de 2018-04-05 10-34-12

/**
 * ... And are "casted" as string when explicitely documented (except for
 * objects that does not displayed at all, jsdoc seems to dislike ``{}``
 * in @param)
 *
 * @param [obj={}] Param JSDoc JSON: ``{"name": "obj="}``?
 * @param [arr=[]]
 * @param [fn=function(){}]
 */
array_object_function_explicite(obj={}, arr=[], fn=function(){}) {
}

capture d ecran de 2018-04-05 10-34-17

Tests with constants

/**
 * Variable or constants as default value are not automatically
 * documented...
 *
 * @param  [a]
 */
constants_implicite(a=SOME_CONST) {
}

capture d ecran de 2018-04-05 10-34-31

/**
 * ... and are seen as string if documented explicitely
 *
 * @param [a=SOME_CONST]
 */
constants_explicite(a=SOME_CONST) {
}

capture d ecran de 2018-04-05 10-34-38

@flozz
Copy link
Contributor
flozz commented Apr 5, 2018

Sorry for the looooong message...^^'

I do not know what is the best thing to do on sphinx-js side:

  • Trusting the types used by jsdoc in its JSON?
  • Just write the default value as is?
  • Trying to be smarter (looking at the param type when available)?

On JSdoc-side:

  • Maybe we can also open an issue... but they will not be able to fix this behavior without breaking things...

Anyway, thank you for asking me to review that PR :)

@erikrose
Copy link
Contributor Author
erikrose commented Apr 5, 2018

To summarize (and get it straight in my head)…

Using the doclet to document defaults lets you use [], {}, function(), and other complex values. However…

  • Interfacing with that the simple way, by merely inserting the doclet text verbatim into our generated params, conflicts with the JSDoc docs, which never use quotes for strings. We would have to use some heuristic (as JSDoc does), which destroys the unambiguity we seek.
  • Using the declared type information to guide our interpretation of the default value would help for any value that can be read as JSON (false, 42, [], {}), but dynamic values (like a function call that returns an int) would fail. I suppose, in case of failure, we could fall back to including the text verbatim. (JSDoc would also like to fix this on its side, but it doesn't look like it will happen soon.)

Documenting defaults solely in the JS code is the other option. But this limits you to the types JSDoc can extract: true, 42, "string", and null.

And unfortunately, sphinx-js doesn't receive both the doclet and the JS default: we get only the union JSDoc computes. So the best course I see is to use the explicit type declaration, if any, to interpret. If we have a declaration and it is "string", put quotes around the literal text and stitch it into our template. Otherwise, omit the quotes. But this, too, has a problematic corner case: if the type declaration is a disjunction like {Array|string} and the default is [] (which comes through to sphinx-js as "[]", bizarrely), we won't know what to do. I suppose we could just take the first one and document our heuristic. I wonder if all that will actually work. Thoughts?

I also looked at the possibility of using workarounds: for simple_type_explicite and array_object_function_explicite, I'd recommend leaving out the doclet bits that confuse JSDoc. I'm not sure where the "" is coming from in simple_type_explicite2; that warrants investigation. For array_object_function_implicite, constants_implicite, and constants_explicite, I think all we can do for now is to document the default in the description part of the doclet, as in "Default: []".

@flozz
Copy link
Contributor
flozz commented Apr 5, 2018

Maybe the simplest thing to do is to

  • use the verbatim "defaultvalue"
  • and document that to have a proper result, the default values must be explicitly documented in the doclet,
  • and that quotes must be included when documenting a string, unlike what jsdoc say in its doc (so writing @param [s="foo"] instead of @param [s=foo])

this should avoid any confusion and let the user decide what is displayed

@erikrose
Copy link
Contributor Author
erikrose commented Apr 5, 2018 via email

< 8000 a class="author Link--primary text-bold" data-test-selector="pr-timeline-events-commit-actor-profile-link" data-hovercard-type="user" data-hovercard-url="/users/erikrose/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="/erikrose">erikrose added 2 commits April 16, 2018 10:51
...which I suspect I need to make the `\"` in my new tests come out right.
* No type that JSDoc extracts correctly from the formal param list needs a type hint: bools, numbers, strs, null.
* Variable references or complex expressions like arrow functions can be documented by including the default in the doclet, as long as you declare a non-string type on it.
* Defaults from doclets for which JSDoc infers the wrong types, like the strings "true" or "42", can be corrected by declaring the correct type in the doclet.
* Param names and default values that contain special ReST chars are now properly escaped.

If you have a tricky disjoint type like `{string|Array}`, specify string first if you want your default to be interpreted as a string.
@erikrose
Copy link
Contributor Author

How does this strike you, @flozz? It still needs documentation in the readme, but this way, you can express anything, ES2016-style defaults are always interpreted as correctly as JSDoc allows, and we don't deviate from JSDoc's documented spellings.

@flozz
Copy link
Contributor
flozz commented Apr 17, 2018

For me, it is the right compromise. I tested on my project and it worked just fine :D

@erikrose erikrose merged commit 967dba6 into master Apr 20, 2018
@erikrose
Copy link
Contributor Author

And I published 2.5 on PyPI. Cheers!

hoodmane added a commit to hoodmane/sphinx-js that referenced this pull request Sep 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0