swallowzhang / jsdoc-toolkit

Automatically exported from code.google.com/p/jsdoc-toolkit
0 stars 0 forks source link

Public class inside namespace gets documented ass inner instead of static member #264

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create classes inside a namespace like this:

/**
@namespace
*/
var TestNamespace = new function(){
    /**
    @class
    */
    var privateClass = function(){

    }

    /**
    @public
    @class
    */
    var publicClass1 = function(){

    }

    /**
    @class
    */
    this.publicClass2 = function(){

    }
}

2. Create the documentation.

What is the expected output? What do you see instead?

//Expected
TestNamespace-privateClass
TestNamespace.publicClass1
TestNamespace.publicClass2

//Actual
TestNamespace-privateClass
TestNamespace-publicClass1
TestNamespace.publicClass2

What version of the product are you using? On what operating system?

2.3.0 on Windows XP

Please provide any additional information below.

publicClass1 is defined as a var instead of a this, thats why I have to put
the @public to force it public, but the toolkit seems to be ignoring this
tag and documents it as an inner class.

Original issue reported on code.google.com by jbm...@gmail.com on 2 Nov 2009 at 4:46

GoogleCodeExporter commented 8 years ago
I've been looking at this, and it seems to me (the guy who created the @public 
tag) that the @public tag is broken on 
a conceptual level. For one thing the idea of "inner" is not the same as 
"private" so it doesn't make sense to use the 
opposite tag, "public" to make something "not inner". In other words the 
behavior you cite as a defect seems to be 
the correct behavior, and the problem actually lies in a misunderstanding of 
what "public" means - I list myself first 
among those with that misunderstanding.

Basically I can't think of any good use for a @public tag -- ever. So let's 
ignore it for now, and talk about how to 
solve your problem.

You have a symbol which is actually named TestNamespace-publicClass1 and, via 
that particualr name, is 
inaccessible from out side TestNamespace scope. Simply saying it's "public" 
isn't enough information to document it, 
you also need to indicate what name people should use to access it by. Maybe, 
as you were typing that @public tag 
you were thinking "I want people to get at this via the name 
TestNamespace.publicClass1." That's fine, but it would 
be even better if you told JsDoc Toolkit about your intention:

/**
@namespace
*/
var TestNamespace = new function(){
    /**
    @class
    */
    var privateClass = function(){

    }

    /**
    @alias TestNamespace.publicClass1
    @class
    */
    this.publicClass1 = function(x, y) {
        /** A method of the inner class. */
        this.doSomething = function() {
        }

    }

    /**
    @class
    */
    this.publicClass2 = function(){

    }
}

Now you may notice I used an undocumented tag there, @alias. Don't panic, even 
though it's not documented it has 
been included in every copy of JsDoc Toolkit ever released and I would consider 
it perfectly safe to rely on. It is 
similar to @name except that it doesn't cause JsDoc Toolkit to ignore the 
surrounding code as @name does. I'd 
suggest you try it and see if it works as you expect. Besides, based on this, I 
intend to add @alias to the docs and 
deprecate @public.

Original comment by micmath on 5 Nov 2009 at 12:29

GoogleCodeExporter commented 8 years ago
Thanks for your reply.

Ok, I think I understand better now.

I have been thinking about what you worte and did some tests with @name and 
@alias.

@name did what I needed to do, @alias didn't. 

I tried this:
/**
@namespace
*/
var Namespace = new function(){
    /**
        @class
        @alias Namespace.PrivateClass
    */
    var PrivateClass = function(){

    }
}
but the class still gets documented as Namespace-PrivateClass.

Maybe it's because I used a var instead of a this.
I don't really understand the difference between @name and @alias, but if @name 
does
the work then it's ok for me.

Now, about the @public tag I think I agree with you, it's kind of confusing.

But it's not only a problem with the @public tag, I think it's kind of hard to 
know
what to use when you want to change something's scope.
Mainly because there's more than one way to do it. I understand there's more 
than one
way for flexibility reasons and beacuse javascript is not purely OO, and that's 
ok. 

So I tried to make a set of rules for scope changing just to see if I'm getting 
it
right or I'm missing something, correct me if I'm wrong.

There are three types of scope: instance(#), static(.) and inner(-).
Depending on how you define something, it will take one of those three scopes
relative to it's parent.
If you don't like the default scope you get, you can change it like this:

If you want to force a member to become inner to it's parent:
    -use @inner

If you want to force a member to become static to it's parent:
    -use @static except if the member is a class in which case the @static will apply to
the member's children.
    -when @static doesn't work, use @name or @alias (the bad thing is it forces you to
put the names).

If you want to force a member to become instance to it's parent:
    -use @public if the parent is class (the public tag should not be used for other
purposes).

In general you can use @name or @alias for any of thones cases, the problem is 
it
forces you to put the names even when you don't want to change them.
The @inner tag seems to be the only case that always works the same.
The @static has a different meaning, sometimes applies to the member and 
sometimes to
it's children.
And for the instance case, there's no tag at all. Maybe @public, but it works 
for
some cases only.

Maybe @public should be deprecated (even @private, this one is even more 
useless if
you already have @inner).
But there should be a easier and more straight forward way to change somethings 
scope
without forcing you to use @name and @alias.
Maybe something like @inner, @instance and @static (@static already has a 
different
meaning, so maybe not...), and then let @name and @alias for the cases when you
really want to change somethings definition (it's name, parent, whatever).

The problem really, is that I have a very big namespace, with dozens of classes 
(even
more namespaces nested). Right now I'm using -a and have only put the @class to 
them.
I thought maybe there was a easier way to make this classes static members of 
their
namespace without having to @name them all.
Maybe I have this problem beacuse I'm writing the code like in C# (classes
definitions inside namespaces).
If that's the only way to go I'll do it that way, I just thought maybe there was
another way.

There are a lot of tags and I'm kind of new to this framework.

Original comment by jbm...@gmail.com on 5 Nov 2009 at 8:00

GoogleCodeExporter commented 8 years ago
I've had a think about this topic and your suggestions. In general I am always 
more willing to shorten the list of supported 
tags, rather than add to it. And I think there is an obvious answer already 
available, the @memberOf tag:

/**
@namespace
*/
var TestNamespace = new function(){
    /**
    @class
    */
    var privateClass = function(){

    }

    /**
    @class
    @memberOf TestNamespace
    */
    var publicClass1 = function(){

    }

    /**
    @class
    */
    this.publicClass2 = function(){

    }
}

// Expected
// TestNamespace-privateClass
// TestNamespace.publicClass1
// TestNamespace.publicClass2
// 
// Actual
// TestNamespace-privateClass
// TestNamespace.publicClass1
// TestNamespace.publicClass2

Unfortunately @memberOf is currently broken in this regard. I will be 
committing a fix later today though, and I think the 
recommended way of solving these problems going forward will be to use 
@memberOf.

The @private tag is not useless, but I admit it is confusingly similar to 
@inner.

Original comment by micmath on 8 Nov 2009 at 7:45

GoogleCodeExporter commented 8 years ago
Fix to @memberOf committed in revision 819.

Original comment by micmath on 8 Nov 2009 at 8:22