Closure Compiler と JsDoc3 @lendsの書き方

@lendsの書き方についての覚書

いちいちClass.prototype.method = function(){};といった書き方をするのは面倒なので、

なんらかの関数でオブジェクトを受け取ってprototypeに関数を定義することが多いと思う。

たとえば以下の様なコード

function defineMethods(clazz, instance_methods) {
    if (instance_methods) {
        for (var k in instance_methods) {
            if (instance_methods.hasOwnProperty(k))
                clazz.prototype[k] = instance_methods[k];
        }
    }
};

/** @interface */
function Interface(){};

/** @expose */
Interface.prototype.say = function() {};

/** @constructor
 * @implements {Interface} */
function ConcreteClass() {
};

defineMethods(ConcreteClass, /** @lends {ConcreteClass.prototype} */ {
    say: function() { console.log('hoge'); }
});

window['ConcreteClass'] = ConcreteClass;

これでClosureは正常にコードを出力してくれるのだが、JsDoc3ではsayがConcreteClassのmethodsの一覧にのってこない。

@lendsの書式は以下のページにある通りで、Closure側にあわせた形。

https://developers.google.com/closure/compiler/docs/js-for-compiler

一方、JsDoc3では@lendsは以下

http://usejsdoc.org/tags-lends.html

@lends は {} で囲わずに普通に名前を書くとなっている。

もともと、{}は 型 を示すときに使う記号なので、JsDoc側の記述の方が自然に思うので そちらにあわせてみる。

function defineMethods(clazz, instance_methods) {
    if (instance_methods) {
        for (var k in instance_methods) {
            if (instance_methods.hasOwnProperty(k))
                clazz.prototype[k] = instance_methods[k];
        }
    }
};

/** @interface */
function Interface(){};

/** @expose */
Interface.prototype.say = function() {};

/** @constructor
 * @implements {Interface} */
function ConcreteClass() {
};

defineMethods(ConcreteClass, /** @lends ConcreteClass.prototype */ {
    say: function() { console.log('hoge'); }
});

window['ConcreteClass'] = ConcreteClass;

これを ADVANCED OPTIMIZATIONSでコンパイルすると以下の通りできちんと認識できているみたい。

X:\>jscomp --warning_level VERBOSE --compilation_level ADVANCED_OPTIMIZATIONS a.js
function a(){}var b={<strong>say</strong>:function(){console.log("hoge")}},c;for(c in b)b.hasOwnP
roperty(c)&&(a.prototype[c]=b[c]);window.ConcreteClass=a;

ということで、@lends xxxと書く事にして、@lends {xxx}は使わない事にする。