More work on the schema.

This commit is contained in:
Michael Mathews 2010-08-03 21:12:10 +01:00
parent 931d2ee6bf
commit 1170f87b15
7 changed files with 339 additions and 206 deletions

View File

@ -194,7 +194,11 @@
tagValue = tag.value;
}
}
if (tagAbout.exportName) {
tagName = tagAbout.exportName;
}
if (tagValue) {
if (typeof o[tagName] === 'undefined') { // not defined
o[tagName] = tagAbout.forceArray? [tagValue] : tagValue;

View File

@ -7,166 +7,281 @@
exports.jsdocSchema = {
"properties": {
"doc": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": { // unique identifier for each doc
"type": "string",
"maxItems": 1
"doc": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"author": {
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"path": { // unique identifier for each doc
"type": "string",
"maxItems": 1
},
"desc": { // a description
"type": "string",
"optional": true,
"maxItems": 1
},
"classdesc": { // a description of the class that this constructor belongs to
"type": "string",
"optional": true,
"maxItems": 1
},
"name": { // probably a trailing substring of the path
"type": "string",
"maxItems": 1
},
"version": { // what is the version of this doc
"type": "string",
"optional": true,
"maxItems": 1
},
"since": { // at what previous version was this doc added?
"type": "string",
"optional": true,
"maxItems": 1
},
"see": { // some thing else to consider
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"deprecated": { // is usage of this symbol deprecated?
"type": ["string", "boolean"],
"optional": true
},
"desc": { // a description
"type": "string",
"optional": true,
"maxItems": 1
},
"name": { // probably a trailing substring of the path
"type": "string",
"maxItems": 1
},
"scope": { // how is this symbol attached to it's enclosing scope?
"type": "string",
"maxItems": 1,
"enum": ["global", "static", "instance", "inner"]
},
"memberof": { // probably a leading substring of the path
"type": "string",
"optional": true,
"maxItems": 1
},
"kind": { // what kind of symbol is this?
"type": "string",
"maxItems": 1,
"enum": ["constructor", "module", "event", "namespace", "method", "property", "enum", "class", "interface", "constant", "mixin", "file", "version"]
},
"refersto": { // the path to another doc: this doc is simply a renamed alias to that
"type": "string",
"optional": true,
"maxItems": 1
},
"access": { // what access priviledges are allowed
"type": "string",
"optional": true,
"maxItems": 1,
"enum": ["private", "protected", "public"]
},
"attrib": { // other attributes, like "readonly"
"type": "string",
"optional": true,
},
"type": { // what type is the value that this doc is associated with, like "number"
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"param" : { // are there function parameters associated with this doc?
"type": "array",
"optional": true,
"items": {
"type": "object",
"properties": {
"type": { // what are the types of value expected for this parameter?
"type": "array",
"optional": true,
"items": {
"type": "string"
}
},
"isoptional": { // is a value for this parameter optional?
"type": "boolean",
"optional": true,
"default": true
},
"isnullable": { // can the value for this parameter be null?
"type": "boolean",
"optional": true,
"default": true
},
"defaultvalue": { // what is the default value for this parameter?
"type": "string",
"optional": true
},
"name": { // what name does this parameter have within the function?
"scope": { // how is this symbol attached to it's enclosing scope?
"type": "string",
"maxItems": 1,
"enum": ["global", "static", "instance", "inner"]
},
"memberof": { // probably a leading substring of the path
"type": "string",
"optional": true,
"maxItems": 1
},
"extends": { // the path to another constructor
"type": "string",
"optional": true,
"maxItems": 1
},
"requires": { // the symbol being documented requires another symbol
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"implements": {
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"kind": { // what kind of symbol is this?
"type": "string",
"maxItems": 1,
"enum": ["constructor", "module", "event", "namespace", "method", "property", "enum", "class", "interface", "constant", "mixin", "file", "version"]
},
"refersto": { // the path to another doc: this doc is simply a renamed alias to that
"type": "string",
"optional": true,
"maxItems": 1
},
"access": { // what access priviledges are allowed
"type": "string",
"optional": true,
"maxItems": 1,
"enum": ["private", "protected", "public"]
},
"attrib": { // other attributes, like "readonly"
"type": "string",
"optional": true
},
"type": { // what type is the value that this doc is associated with, like "number"
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"exception" : {
"optional": true,
"type": "object",
"properties": {
"type": { // what is the type of the value thrown?
"type": "array",
"optional": true,
"items": {
"type": "string"
},
"desc": { // a description of the parameter
"type": "string",
"optional": true
}
},
"desc": { // a description of the thrown value
"type": "string",
"optional": true
}
}
},
"tag": { // arbitrary tags associated with this doc
"type": "array",
"optional": true,
"items": {
"type": "object",
"properties": {
"name": { // the name of a tag
},
"additionalProperties": false
},
"returns" : {
"optional": true,
"type": "object",
"properties": {
"type": { // what is the type of the value returned?
"type": "array",
"optional": true,
"items": {
"type": "string"
},
"desc": { // a value associated with that tag name
"type": "string",
"optional": true
}
},
"desc": { // a description of the returned value
"type": "string",
"optional": true
}
}
},
"meta": { // information about this doc
"type": "object",
"optional": true,
"maxItems": 1,
"file": { // what is the name of the file this doc appears in?
},
"additionalProperties": false
},
"param" : { // are there function parameters associated with this doc?
"type": "array",
"optional": true,
"items": {
"type": "object",
"properties": {
"type": { // what are the types of value expected for this parameter?
"type": "array",
"optional": true,
"items": {
"type": "string"
}
},
"optional": { // is a value for this parameter optional?
"type": "boolean",
"optional": true,
"default": true
},
"nullable": { // can the value for this parameter be null?
"type": "boolean",
"optional": true,
"default": true
},
"defaultvalue": { // what is the default value for this parameter?
"type": "string",
"optional": true
},
"name": { // what name does this parameter have within the function?
"type": "string"
},
"desc": { // a description of the parameter
"type": "string",
"optional": true
}
},
"additionalProperties": false
}
},
"thisobj": {
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"example": { // some thing else to consider
"type": ["string", "array"],
"optional": true,
"items": {
"type": "string"
}
},
"tags": { // arbitrary tags associated with this doc
"type": "array",
"optional": true,
"additionalProperties": false,
"items": {
"type": "string"
}
},
"meta": { // information about this doc
"type": "object",
"optional": true,
"maxItems": 1,
"properties": {
"file": { // what is the name of the file this doc appears in?
"type": "string",
"optional": true,
"maxItems": 1
},
"line": { // on what line of the file does this doc appear?
"type": "number",
"optional": true,
"maxItems": 1
}
},
"additionalProperties": false
}
}
}
},
"meta": { // information about the generation for all the docs
"type": "object",
"optional": true,
"maxItems": 1,
"properties": {
"project": { // to what project does this doc belong?
"type": "object",
"optional": true,
"maxItems": 1,
"properties": {
"name": { // the name of the project
"type": "string",
"optional": true,
"maxItems": 1
},
"line": { // on what line of the file does this doc appear?
"type": "number",
"optional": true,
"uri": { // the URI of the project
"type": "string",
"maxItems": 1,
"format": "uri"
},
"version": { // the version of the project
"type": "string",
"maxItems": 1
},
"lang": { // the programming language used in the project
"type": "string",
"maxItems": 1
}
}
}
}
},
"meta": { // information about the generation for all the docs
"type": "object",
"optional": true,
"maxItems": 1,
"project": { // to what project does this doc belong
"type": "object",
"optional": true,
"maxItems": 1,
"name": { // the name of the project
"type": "string",
"maxItems": 1
},
"additionalProperties": false
},
"uri": { // the URI of the project
"type": "string",
"maxItems": 1,
"format": "uri"
}
},
"generated": { // some information about the running of the doc generator
"type": "object",
"optional": true,
"maxItems": 1,
"date": { // on what date and time was the doc generated?
"type": "string",
"maxItems": 1,
"generated": { // some information about the running of the doc generator
"type": "object",
"optional": true,
"format": "date-time"
},
"parser": { // what tool was used to generate the doc
"type": "string",
"maxItems": 1,
"optional": true
"properties": {
"date": { // on what date and time was the doc generated?
"type": "string",
"maxItems": 1,
"optional": true,
"format": "date-time"
},
"parser": { // what tool was used to generate the doc?
"type": "string",
"maxItems": 1,
"optional": true
}
},
"additionalProperties": false
}
}
}
}
}
}
};

View File

@ -71,7 +71,7 @@
if (type && type.length) { this.type = type; }
// @type tags are special: their type *is* their value
if (this.name === 'type') {
if (tagAbout.typeIsValue) {
value = (this.type[0] === '')? this.value.split(/\s*\|\s*/g) : this.type;
if (value.length === 1) value = value[0]; // single values don't need to be arrays
this.type = [];

View File

@ -81,7 +81,9 @@
keepsWhitespace : false, // don't try to tidy up the whitespace in this tag?
impliesTag : false, // this tag implies another tag
isScalar : false, // can only have a single value (first wins)
forceArray : false // must always be an array
forceArray : false, // must always be an array,
typeIsValue : false,
exportName : '' // what name will this tag be exported as (defaults to tag name)
};
/** Syntax: @access <text> (private|public|protected)
@ -147,7 +149,8 @@
@memberOf module:jsdoc/tagdictionary~tagDefinitions
*/
new TagDefinition('memberof', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @namespace <docletType> <docletName>
@ -312,7 +315,8 @@
*/
new TagDefinition('type', {
isExported: true,
canHaveType: true
canHaveType: true,
typeIsValue: true
});
/** Syntax: @returns|return <returnType> <text>
@ -322,7 +326,8 @@
new TagDefinition('returns', {
isExported: true,
canHaveType: true,
canHavePdesc: true
canHavePdesc: true,
isScalar: true
});
/** Syntax: @thisobj|this <thisobjType> <text>
@ -332,7 +337,7 @@
new TagDefinition('thisobj', {
isExported: true,
canHaveType: true,
canHavePdesc: true,
typeIsValue: true,
isScalar: true
});
@ -476,8 +481,7 @@
*/
new TagDefinition('tag', {
isExported: true,
canHavePname: true,
canHavePdesc: true,
exportName: 'tags',
forceArray: true
});
@ -503,7 +507,8 @@
@memberOf module:jsdoc/tagdictionary~tagDefinitions
*/
new TagDefinition('refersto', {
isExported: true
isExported: true,
isScalar: true
});
/** Syntax: @implements <text>
@ -511,6 +516,8 @@
@memberOf module:jsdoc/tagdictionary~tagDefinitions
*/
new TagDefinition('implements', {
isExported: true
isExported: true,
canHaveType: true,
typeIsValue: true
});
})();

View File

@ -89,7 +89,7 @@ Shape.prototype.color = null;
/**
* The border of this shape.
* @field
* @type int
* @type {int}
*/
Shape.prototype.border = function(){return border;};
@ -133,14 +133,14 @@ Shape.prototype.setCoords = function(coordinates){
/**
* Set the color for this Shape
* @method
* @param {Color} color The color to set for this Shape
* @param {?Color} [color=black] The color to set for this Shape
* @param other There is no other param, but it can still be documented if
* optional parameters are used
* @throws NonExistantColorException (no, not really!)
* @see #getColor
*/
Shape.prototype.setColor = function(color){
this.color = color;
this.color = color || new Color(0, 0, 0);
}
/**
@ -163,7 +163,7 @@ Shape.prototype.clone = function(){
* @param {int} height Thie optional height for this Rectangle
* @author Gabriel Reid
* @see Shape is the base class for this
* @augments Shape
* @extends Shape
* @hilited
*/
function Rectangle(width, // This is the width
@ -177,7 +177,6 @@ function Rectangle(width, // This is the width
}
}
/* Inherit from Shape */
Rectangle.prototype = new Shape();
@ -259,7 +258,7 @@ Rectangle.prototype.getArea = function(){
* @class A Square is a subclass of {@link Rectangle}
* @param {int} width The optional width for this Rectangle
* @param {int} height The optional height for this Rectangle
* @augments Rectangle
* @extends Rectangle
*/
function Square(width, height){
if (width){
@ -304,6 +303,11 @@ function Circle(radius){
/** The radius of the this Circle. */
this.radius = radius;
}
/**
* @property
*/
this.area = getArea.call(this);
}
/* Circle inherits from {@link Shape} */
@ -434,10 +438,11 @@ function ShapeFactory(){
ShapeFactory.prototype = {
/**
* Creates a new {@link Shape} instance.
* @param {!Object=} opts An options object that is optional but can't be null.
* @return A new {@link Shape}
* @type Shape
*/
createShape: function(){
createShape: function(opts){
return new Shape();
}
}
@ -488,3 +493,29 @@ Foo.Bar = function(){
Foo.Bar.prototype = new Bar();
/** The y. */
Foo.Bar.prototype.y = '3';
// private method, as in the module pattern
/**
* @private
* @this {Circle}
*/
function getArea() {
}
// see http://www.integralist.co.uk/javascript/implementing-interfaces-in-javascript/
/** @interface */
var threeD = new Interface('threeD');
/**
Getter and setter for the z axis.
@instance
@method
@param {number} v
*/
threeD.axisZ = Interface.method('number:v');
/** @class
@implements {threeD}
*/
function Cube(opts) {
Interface.ensureImplements(opts.methods, threeD);
}

View File

@ -2,13 +2,13 @@
@tag hilited
*/
/** @namespace bar
@tag api developer
/** @namespace baz
@tag experimental
@tag lots of words
*/
/** @namespace baz
@tag support - experimental
@tag api internal
/** @namespace bar
@tag
*/
/** @namespace zub

View File

@ -2,7 +2,7 @@
var jsdoc,
doclets;
JSpec.describe('@scope', function() {
JSpec.describe('@tag', function() {
before(function() {
// docsets can only be created by parsers
@ -18,57 +18,33 @@
describe('A doclet with single @tag <name>', function() {
it('should have a `tag` property of type array with a single member', function() {
var doclet = doclets[0];
expect(doclet).to(have_property, 'tag');
expect(doclet.tag).to(be_an, Array);
expect(doclet.tag.length).to(be, 1);
expect(doclet).to(have_property, 'tags');
expect(doclet.tags).to(be_an, Array);
expect(doclet.tags.length).to(be, 1);
});
it('that tag should have a name property set to <name>, and no description property', function() {
var doclet = doclets[0];
expect(doclet.tag[0]).to(have_property, 'name');
expect(doclet.tag[0].desc).to(be_undefined);
expect(doclet.tag[0].name).to(be_an, String);
expect(doclet.tag[0].name).to(be, 'hilited');
expect(doclet.tags[0]).to(be_an, String);
expect(doclet.tags[0]).to(be, 'hilited');
});
});
describe('A doclet with single @tag <name> <desc>', function() {
describe('A doclet with two @tag <name>', function() {
it('should have a tag with a name property set to <name>, and description set to <desc>', function() {
var doclet = doclets[1];
expect(doclet.tag[0]).to(have_property, 'name');
expect(doclet.tag[0]).to(have_property, 'desc');
expect(doclet.tag[0].name).to(be_an, String);
expect(doclet.tag[0].name).to(be, 'api');
expect(doclet.tags[0]).to(be_an, String);
expect(doclet.tags[0]).to(be, 'experimental');
expect(doclet.tag[0].desc).to(be_an, String);
expect(doclet.tag[0].desc).to(be, 'developer');
expect(doclet.tags[1]).to(be_an, String);
expect(doclet.tags[1]).to(be, 'lots of words');
});
});
describe('A doclet with two @tag <name> <desc>', function() {
it('should have a tag property set to an array of length 2', function() {
describe('A doclet with an empty @tag', function() {
it('should have no tag property', function() {
var doclet = doclets[2];
expect(doclet).to(have_property, 'tag');
expect(doclet.tag).to(be_an, Array);
expect(doclet.tag.length).to(be, 2);
});
});
describe('A doclet with two @tag <name> - <desc>', function() {
it('should have a tag property with a name property set to <name>, and description set to <desc>', function() {
var doclet = doclets[2];
expect(doclet.tag[0]).to(have_property, 'name');
expect(doclet.tag[0]).to(have_property, 'desc');
expect(doclet.tag[0].name).to(be, 'support');
expect(doclet.tag[0].desc).to(be, 'experimental');
});
});
describe('A doclet with no @tag', function() {
it('should not have a tag property', function() {
var doclet = doclets[3];
expect(doclet.tag).to(be_undefined);
expect(doclet.tags).to(be_undefined);
});
});