Skip to content
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

Visibility of constructors is handled wrong #952

Closed
BlackWolf opened this issue Mar 13, 2015 · 15 comments
Closed

Visibility of constructors is handled wrong #952

BlackWolf opened this issue Mar 13, 2015 · 15 comments
Labels
Milestone

Comments

@BlackWolf
Copy link

I just noticed that the visibility of constructors (when using protoyping) seems to behave strangely. The main issue here seems to be that JSDoc does not permit classes without constructors, which can happen if the class is created internally (protected) but user's should be permitted access to the members and methods of instances.

Example:

/**
 * Some description
 * @protected
 */
function AClass() {
    ...
}

/**
 * The method description
 * @public
 */
AClass.prototype.aMethod = function() {
    ...
}

When using jsdoc with -a public, the entire class AClass does not show up in the documentation, even though aMethod is declared as public.


Another example:

/**
 * @class AClass
 * @classdesc Some class description
 */

/**
 * Some description
 * @protected
 */
function AClass() {
    ...
}

Here, using -a public leads to the class being in the documentation, but the constructor is also documented, even though it is marked as protected.

@hegemonic
Copy link
Contributor

It's true that JSDoc doesn't draw much of a distinction between "a class" and "a constructor for a class." As a result, it doesn't make sense to use the @protected tag on a class that you want users to know about. (I don't think this behavior is "wrong"--it's just not what you want.)

It sounds like what you really need is a way to say "hey, JSDoc, don't display a constructor for this class." I'm open to adding a tag for that purpose, but I'm not sure what to call it. All I'm coming up with right now is @noconstructor, which is not so great.

@whitlockjc
Copy link

I would love this feature as well and I am going to throw some ideas out there, although I'm not saying all of them are good:

  • @constructed
  • @donotcall
  • @internal
  • @noninstantiable
  • @moduleuseonly
  • @nonew
  • @provided
  • @useatownrisk

My favorites are @internal and @provided. @internal to me says this is available for use within the module but not intended to be used by consumers. @provided says the same thing, although in the DI world I can see how that could be confusing.

In the end, we need some way to say This object has properties/functions that need documentation but this object is not intended to be constructed outside the owning module.

@whitlockjc
Copy link

By the way, in the meantime I just throw some HTML into my jsdocs and it renders fine:

/**
 * My constructor object that is created internally but never expected to be used externally.
 *
 * <strong>Note:</strong> Do not use directly.
 *
 * @constructor
 */

@matthoz
Copy link

matthoz commented Sep 23, 2015

I've got the same issue. In our framework, several modules are used to be initalized only once.

It's like:

/**
 * @class
 * @this {namespace.MyClass}
 * @return {namespace.MyClass}
 */
 namespace.MyClass = function(oAttributes) {
    //Public and local scope functions...
    //...

    /**
     * ...
     * @function namespace.MyClass.publicMethod
     */
    this.publicMethod = function() {
    }

    return this;
}

//overwrite self with instance.
namespace.MyClass = new namespace.MyClass();

And in the Documentation namespace.MyClass will be shown with constructor:
new MyClass ()

In my opinion, it is unnecessary to create a new tagname. If a class marked as static with the @static tag, there should not appear a constructor statement.

But there is another case in which a certain class is used as a superclass and should only be used like this:

    namespace.superclass.call(this, true)

I'm currently using @classdesc to describe how to use this class, because it will show up before the constructor.

@golgobot
Copy link

Any updates on this? Would love to have this.

@henridf
Copy link

henridf commented Dec 14, 2015

Just ran into same issue. Would be great to have a way to tell jsdoc not to display the constructor.

@machty
Copy link

machty commented Feb 18, 2016

Hacker beware:

  <style>
    .ignore-this--this-is-here-to-hide-constructor,
    #TaskProperty { display: none }
  </style>

and s/TaskProperty/NameOfYourClass

@tregusti
Copy link

tregusti commented May 30, 2016

Well, personally I think the problem is another. The fact that there is no (?) difference between a constructor and a class.

I find this to be the single biggest problem with JSDoc throughout all my projects and workplaces.

Any good documentation a class is decribed on a high level with some examples to get a grasp of the class in general. This should be able to include @examples and many other tags.

A constructor, is just one, of potentially several ways to create the object, and does not fit for having the responsibility to show the examples I mentioned above.

Ignoring that @class and @constructor currently is the same thing in JSDoc I would like to do something like this:

/**
* @class
* A good and long multi paragraph description of the Person.
* @example 
* // Use like this
* const p = new Person('Glenn', 'Jorde');
* @example 
* // Or this
* const p = new Person('Glenn Jorde');
*/
class Person {
  /**
  * @constructor
  * @param {String} first Specify first name, when second argument is missing this will be the full name
  * @param {String} [last=null] Last name.
  * @throws {ArgumentError} When missing `firstname`.
  */
  constructor(first, last=null) {
    if (arguments.length === 1) {
      this.name = first;
    } else {
      this.name = `${first} ${last}`;
    }
    // Input validation or something
  }
}

And these should render separately. And the data object between them should be easy to see what is what.

And as a bonus out of this solution there is no problem whatsoever to just omit the doclet with the @constructor to simply not show it in the documentation.

http://usejsdoc.org/howto-es2015-classes.html mentions how to document ES2015 classes, but the first doclet only supports a single line of text. Not a full doclet with examples etc. And yes, I'm sure this is possible to hack together with custom templates, but I really feel that this should be the default case.

Hopefully you understand what I mean. I typed it rather quickly.

@Rob46
Copy link

Rob46 commented Jan 31, 2017

Need this too.

I also think it is good have have class level documentation even if the class only has a private or protected constructor.

Maybe this can be solved by having a tag like @Class {public} and then it can also have @constructor {public/private/protected/ignore/internal}

Maybe something like this:

/**
 * My class overview with examples.
 * @class {public}
 * @constructor {ignore}
 */

@jsdoc jsdoc deleted a comment from mllanes Jul 2, 2017
@jsdoc jsdoc deleted a comment from philipp-spiess Jul 2, 2017
@jsdoc jsdoc deleted a comment from WeeJeWel Jul 2, 2017
@jsdoc jsdoc deleted a comment from pzp1997 Jul 2, 2017
@hegemonic hegemonic modified the milestones: 3.5.0, Future Jul 2, 2017
hegemonic added a commit that referenced this issue Jul 7, 2017
@hegemonic
Copy link
Contributor

Fixed on master. JSDoc now supports a @hideconstructor tag, and if this tag is added to a class, the default template will not show the constructor. (Third-party templates will need to be updated to support this feature.)

The fix will be included in JSDoc 3.5.0.

@schmidt-sebastian
Copy link

I would also like to further suggest that the constructor parameters should not show up in the class description when@hideconstructor is used. My documentation is much cleaner now, but I am still leaking internal implementation details in the public documentation.

@hegemonic
Copy link
Contributor

@schmidt-sebastian That's a bug, not the intended behavior. I filed #1397 and will fix this soon.

@computerquip-streamlabs
Copy link

computerquip-streamlabs commented Jul 25, 2017

I'm not sure I understand. I'm adding a @hideconstructor tag to my class but it still shows the default constructor.

/**
  * @classdesc Some desc
  * @class
  * @name SomeClass
  * @hideconstructor
  */

seems to fail to hide the constructor. Using JSDoc 3.5.3

EDIT: I should note that in my case, I'm providing only comments. The declarations are not with the comments.

@hegemonic
Copy link
Contributor

@computerquip-streamlabs Are you using JSDoc's default template? If not, you'll need to ask your template's author to update the template so it supports the @hideconstructor tag.

@computerquip-streamlabs

@hegemonic Ah, I missed that bit. Using the default template shows that it does work. Thanks.

lheberlie added a commit to bsvensson/jsdoc that referenced this issue Aug 15, 2017
3.5.0

* tag '3.5.0': (97 commits)
  3.5.0
  bump revision; start 3.6.0-dev
  update 3.5.0 changelog
  3.5.0 changelog
  reformat changelog
  add yields tag (jsdoc#1388)
  resolve the path to the JS config file before requiring it (jsdoc#1386)
  support namespaces that are also functions (jsdoc#955)
  add hideconstructor tag (jsdoc#952)
  add package tag (jsdoc#962)
  autodetect default and repeatable parameters when a function is assigned to a variable (jsdoc#1054)
  correctly document constructors and instance properties of ES2015 classes (jsdoc#1182)
  add sourceType config option
  fix crash when the author tag is empty (jsdoc#1289)
  add recurseDepth config option (jsdoc#1340)
  support bigint
  support import.meta
  support optional chaining
  support numeric separators
  support dynamic import
  ...

# Conflicts:
#	.eslintrc
#	README.md
#	lib/jsdoc/fs.js
#	lib/jsdoc/opts/args.js
#	lib/jsdoc/src/astbuilder.js
#	lib/jsdoc/src/astnode.js
#	lib/jsdoc/src/handlers.js
#	lib/jsdoc/src/parser.js
#	lib/jsdoc/src/visitor.js
#	lib/jsdoc/src/walker.js
#	lib/jsdoc/tag/dictionary/definitions.js
#	lib/jsdoc/tag/validator.js
#	lib/jsdoc/util/markdown.js
#	lib/jsdoc/util/templateHelper.js
#	package.json
#	templates/default/static/styles/jsdoc-default.css
#	templates/haruki/publish.js
#	test/spec-collection.js
#	test/specs/documentation/defaultparams.js
#	test/specs/documentation/restparams.js
#	test/specs/jsdoc/src/astnode.js
#	test/specs/jsdoc/util/templateHelper.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests