您的位置:首页 > Web前端 > JavaScript

用于Javascript的文档生成软件的开发总结

2011-05-19 20:34 337 查看
  近期一直在做Js文档生成软件。

  目前占据这个领域的主要就是 jsdoc 开源项目。先介绍下 jsdoc 本身,它是用Java开发的(其实主要是Javascript开发) 基于字符串直接处理的文档工具。 因为Javscript非常灵活,Javascript的文档生成自然也比不上Java之类的准确、有效。jsdoc本身要求在注释中大量使用一些标签来告诉文档生成器这是一个类、属性、方法或其它的类型,jsdoc在解析中是通过上下文来决定变量的归属,比如上文使用 @class 标识类, 下文的 @method 就自动处理为上个 @class 所指的类,而完全忽视了代码自身的逻辑。

  且不说jsdoc的方法是否方便、有效。总之,我要做的是基于语法分析而生成文档的工具。 

  我目标是生成完全面向对象阻止的文档,即最后的文档最高级是名字空间(包) , 下级是类, 再下级是成员。

  1. 成员的归类。一个变量在定义后,它到底属于哪个父成员,这是文档分析必须要分析出的。

/**
* 将当前值转为数字。
*/
Boolean.prototype.toNumber = function(){
return +this;
};


  从这段代码可知: 有一个 toNumber 成员, 其父成员为 Boolean.prototype , 这个情况可以轻松检测所在成员,但假如换一个写法,比如 Ext 中的写法是:

/**
* 将当前值转为数字。
*/
Ext.extend(Boolean.prototype,{  toNumber: function(){
return +this;
}}  );


  这就很麻烦了,因为文档分析程序不肯能去执行这个代码,它当然不知道 toNumber 的父成员。 jsdoc采用最近使用的 @class 最为其父成员。但这样很容易导致 @class 多很多错误的成员。

  最终我采用作用域的分析方式。即 函数调用 或 函数定义 被作为一个作用域。它们之前的 @class 将被理解为这个作用域内成员的父成员。即代码应该这样注释:

/**
* 将当前值转为数字。 * @class Boolean
*/
Ext.extend(Boolean.prototype,{  toNumber: function(){
return +this;
}}  );


@class Boolean 只对此函数有效,即 @class 只解释相邻的作用域。 同理有:

/**
* 将当前值转为数字。 * @class Boolean
*/
(function(){  function toNumber(){
return +this;
}})();


由于这是函数定义,所以函数内部的成员的父成员也是 @class Boolean 。

  当然,这些都是无理的推算,肯能导致错误结果,可以通过指定 @memberOf 来覆盖自动判断的父变量。

  以上对于 @class C , 成员解释为 C.prototype.p

  对于 @namespace C , 或成员已记 @static, 解释为 C.p

2. 具备识别继承、原型的功能。

比如 A.prototype = new B 是很典型的继承代码。

通过模拟运行可以实现 原型操作。

3. 根据平时写Javascript的经验,再参考jsdoc, 最终我决定将使用以下几个系统标签,它们将为文档生成做出伟大贡献。

全局标签

  全局标签主要用于全项目或文件的描述。一般全局标签只能在文件顶部使用。

@projectDescription Summary 当前项目功能描述

@author Summary 代码的作者

@lisense Summary 代码的协议

@version Summary 代码的版本

@fileOverview Summary 当前文件描述

@file Summary 表示当前文件名,默认为真实文件名

公开标签

以下标签可以在任何位置使用,就像 HTML 中任何标签都有 tagName 的属性。

@summary Summary 注释的简介 - 一般不需要直接使用这个标签, 因为注释的最开始处到第一个可解析的标签前的文字就是 @summary 标签。即: /** 内容 */ 等价于 /** @summary 内容 */

@remark Summary 备注 - 一般不需要直接使用这个标签, 因为注释中已经使用了标签之后的文字就是 @remark 。即:
  /**
* @return {Number}
   * 说明
*/
等价于
  /**
   * @return {Number}
   * @remark 说明
   */

@ignore 忽略有这个标记注释。

@define {Type} {Type} 定义同意义的类型。 比如 @define {int} {Number} 这样就可以用 int 代替 Number

@define Name Name 定义同意义的注释, 使用 define 可以定义标签的 别名。比如 @define description summary 之后就可用 @description 替代 @summary

@since [Summary] 指示自指定的版本提供。

@deprecated [Summary] 指示一个成员已经废弃。

@see Link 指向一个文件的链接。

@example Summary 示例。

@syntax Summary 手动指定语法。

@name Name 名字。

@memberOf Name 指示父成员。

@type Type 指示类型。

类型说明

@class [Name] 指示这是一个类。

@enum [Name] 指示这是枚举。

@interface [Name] 指示这是一个接口。

@member [Name] 指示这是一个成员。

@property [{Type}] [Name] 指示这是一个属性。

@field [{Type}] [Name] 指示这是一个字段。

@method [Name] 指示这是一个方法。

@event [{Type}] [Name] 指示当前类的事件。

@getter [{Type}] [Name] 指示这是一个只读属性。

@setter [{Type}] [Name] 指示这是一个只写属性。

@constructor [Name] 指示这是构造函数。

@config {Type} [Name] 指示这是类的配置成员。

属性说明

@public 指示公开

@private 指示一个类或函数是私有的。

@protected 指示保护。

@internal 指示内部。

@final 指示一个函数是不能覆盖的。

@static 指示一个类是静态的。

@abstract 指示一个类是抽象的。

@virtual 指示一个类是抽象的。

@const 指示一个值是常量值。

其它

@extends Name 指示一个类派生了另一个类。

@implements Name 指示一个类派生了另一个类。

@param {Type} Name Summary 表示参数。如果是可选参数加上 [Name] ,如果是 随机参数 名字为 ... 如果有默认值, 使用 Name=Value 多类型使用任意符号分开。

@return [{Type}] [Summary] 返回 。

{@link Link} 链接。

{@code [{Type}] <<< Summary >>>} 代码。

@{ 表示字符 {

@@ 表示字符 @

@} 表示字符 }

@* 表示字符 *
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: