| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899 | 
							- /*
 
-  * @fileoverview Main Doctrine object
 
-  * @author Yusuke Suzuki <utatane.tea@gmail.com>
 
-  * @author Dan Tao <daniel.tao@gmail.com>
 
-  * @author Andrew Eisenberg <andrew@eisenberg.as>
 
-  */
 
- (function () {
 
-     'use strict';
 
-     var typed,
 
-         utility,
 
-         jsdoc,
 
-         esutils,
 
-         hasOwnProperty;
 
-     esutils = require('esutils');
 
-     typed = require('./typed');
 
-     utility = require('./utility');
 
-     function sliceSource(source, index, last) {
 
-         return source.slice(index, last);
 
-     }
 
-     hasOwnProperty = (function () {
 
-         var func = Object.prototype.hasOwnProperty;
 
-         return function hasOwnProperty(obj, name) {
 
-             return func.call(obj, name);
 
-         };
 
-     }());
 
-     function shallowCopy(obj) {
 
-         var ret = {}, key;
 
-         for (key in obj) {
 
-             if (obj.hasOwnProperty(key)) {
 
-                 ret[key] = obj[key];
 
-             }
 
-         }
 
-         return ret;
 
-     }
 
-     function isASCIIAlphanumeric(ch) {
 
-         return (ch >= 0x61  /* 'a' */ && ch <= 0x7A  /* 'z' */) ||
 
-             (ch >= 0x41  /* 'A' */ && ch <= 0x5A  /* 'Z' */) ||
 
-             (ch >= 0x30  /* '0' */ && ch <= 0x39  /* '9' */);
 
-     }
 
-     function isParamTitle(title) {
 
-         return title === 'param' || title === 'argument' || title === 'arg';
 
-     }
 
-     function isReturnTitle(title) {
 
-         return title === 'return' || title === 'returns';
 
-     }
 
-     function isProperty(title) {
 
-         return title === 'property' || title === 'prop';
 
-     }
 
-     function isNameParameterRequired(title) {
 
-         return isParamTitle(title) || isProperty(title) ||
 
-             title === 'alias' || title === 'this' || title === 'mixes' || title === 'requires';
 
-     }
 
-     function isAllowedName(title) {
 
-         return isNameParameterRequired(title) || title === 'const' || title === 'constant';
 
-     }
 
-     function isAllowedNested(title) {
 
-         return isProperty(title) || isParamTitle(title);
 
-     }
 
-     function isAllowedOptional(title) {
 
-         return isProperty(title) || isParamTitle(title);
 
-     }
 
-     function isTypeParameterRequired(title) {
 
-         return isParamTitle(title) || isReturnTitle(title) ||
 
-             title === 'define' || title === 'enum' ||
 
-             title === 'implements' || title === 'this' ||
 
-             title === 'type' || title === 'typedef' || isProperty(title);
 
-     }
 
-     // Consider deprecation instead using 'isTypeParameterRequired' and 'Rules' declaration to pick when a type is optional/required
 
-     // This would require changes to 'parseType'
 
-     function isAllowedType(title) {
 
-         return isTypeParameterRequired(title) || title === 'throws' || title === 'const' || title === 'constant' ||
 
-             title === 'namespace' || title === 'member' || title === 'var' || title === 'module' ||
 
-             title === 'constructor' || title === 'class' || title === 'extends' || title === 'augments' ||
 
-             title === 'public' || title === 'private' || title === 'protected';
 
-     }
 
-     // A regex character class that contains all whitespace except linebreak characters (\r, \n, \u2028, \u2029)
 
-     var WHITESPACE = '[ \\f\\t\\v\\u00a0\\u1680\\u180e\\u2000-\\u200a\\u202f\\u205f\\u3000\\ufeff]';
 
-     var STAR_MATCHER = '(' + WHITESPACE + '*(?:\\*' + WHITESPACE + '?)?)(.+|[\r\n\u2028\u2029])';
 
-     function unwrapComment(doc) {
 
-         // JSDoc comment is following form
 
-         //   /**
 
-         //    * .......
 
-         //    */
 
-         return doc.
 
-             // remove /**
 
-             replace(/^\/\*\*?/, '').
 
-             // remove */
 
-             replace(/\*\/$/, '').
 
-             // remove ' * ' at the beginning of a line
 
-             replace(new RegExp(STAR_MATCHER, 'g'), '$2').
 
-             // remove trailing whitespace
 
-             replace(/\s*$/, '');
 
-     }
 
-     /**
 
-      * Converts an index in an "unwrapped" JSDoc comment to the corresponding index in the original "wrapped" version
 
-      * @param {string} originalSource The original wrapped comment
 
-      * @param {number} unwrappedIndex The index of a character in the unwrapped string
 
-      * @returns {number} The index of the corresponding character in the original wrapped string
 
-      */
 
-     function convertUnwrappedCommentIndex(originalSource, unwrappedIndex) {
 
-         var replacedSource = originalSource.replace(/^\/\*\*?/, '');
 
-         var numSkippedChars = 0;
 
-         var matcher = new RegExp(STAR_MATCHER, 'g');
 
-         var match;
 
-         while ((match = matcher.exec(replacedSource))) {
 
-             numSkippedChars += match[1].length;
 
-             if (match.index + match[0].length > unwrappedIndex + numSkippedChars) {
 
-                 return unwrappedIndex + numSkippedChars + originalSource.length - replacedSource.length;
 
-             }
 
-         }
 
-         return originalSource.replace(/\*\/$/, '').replace(/\s*$/, '').length;
 
-     }
 
-     // JSDoc Tag Parser
 
-     (function (exports) {
 
-         var Rules,
 
-             index,
 
-             lineNumber,
 
-             length,
 
-             source,
 
-             originalSource,
 
-             recoverable,
 
-             sloppy,
 
-             strict;
 
-         function advance() {
 
-             var ch = source.charCodeAt(index);
 
-             index += 1;
 
-             if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D  /* '\r' */ && source.charCodeAt(index) === 0x0A  /* '\n' */)) {
 
-                 lineNumber += 1;
 
-             }
 
-             return String.fromCharCode(ch);
 
-         }
 
-         function scanTitle() {
 
-             var title = '';
 
-             // waste '@'
 
-             advance();
 
-             while (index < length && isASCIIAlphanumeric(source.charCodeAt(index))) {
 
-                 title += advance();
 
-             }
 
-             return title;
 
-         }
 
-         function seekContent() {
 
-             var ch, waiting, last = index;
 
-             waiting = false;
 
-             while (last < length) {
 
-                 ch = source.charCodeAt(last);
 
-                 if (esutils.code.isLineTerminator(ch) && !(ch === 0x0D  /* '\r' */ && source.charCodeAt(last + 1) === 0x0A  /* '\n' */)) {
 
-                     waiting = true;
 
-                 } else if (waiting) {
 
-                     if (ch === 0x40  /* '@' */) {
 
-                         break;
 
-                     }
 
-                     if (!esutils.code.isWhiteSpace(ch)) {
 
-                         waiting = false;
 
-                     }
 
-                 }
 
-                 last += 1;
 
-             }
 
-             return last;
 
-         }
 
-         // type expression may have nest brace, such as,
 
-         // { { ok: string } }
 
-         //
 
-         // therefore, scanning type expression with balancing braces.
 
-         function parseType(title, last, addRange) {
 
-             var ch, brace, type, startIndex, direct = false;
 
-             // search '{'
 
-             while (index < last) {
 
-                 ch = source.charCodeAt(index);
 
-                 if (esutils.code.isWhiteSpace(ch)) {
 
-                     advance();
 
-                 } else if (ch === 0x7B  /* '{' */) {
 
-                     advance();
 
-                     break;
 
-                 } else {
 
-                     // this is direct pattern
 
-                     direct = true;
 
-                     break;
 
-                 }
 
-             }
 
-             if (direct) {
 
-                 return null;
 
-             }
 
-             // type expression { is found
 
-             brace = 1;
 
-             type = '';
 
-             while (index < last) {
 
-                 ch = source.charCodeAt(index);
 
-                 if (esutils.code.isLineTerminator(ch)) {
 
-                     advance();
 
-                 } else {
 
-                     if (ch === 0x7D  /* '}' */) {
 
-                         brace -= 1;
 
-                         if (brace === 0) {
 
-                             advance();
 
-                             break;
 
-                         }
 
-                     } else if (ch === 0x7B  /* '{' */) {
 
-                         brace += 1;
 
-                     }
 
-                     if (type === '') {
 
-                         startIndex = index;
 
-                     }
 
-                     type += advance();
 
-                 }
 
-             }
 
-             if (brace !== 0) {
 
-                 // braces is not balanced
 
-                 return utility.throwError('Braces are not balanced');
 
-             }
 
-             if (isAllowedOptional(title)) {
 
-                 return typed.parseParamType(type, {startIndex: convertIndex(startIndex), range: addRange});
 
-             }
 
-             return typed.parseType(type, {startIndex: convertIndex(startIndex), range: addRange});
 
-         }
 
-         function scanIdentifier(last) {
 
-             var identifier;
 
-             if (!esutils.code.isIdentifierStartES5(source.charCodeAt(index)) && !source[index].match(/[0-9]/)) {
 
-                 return null;
 
-             }
 
-             identifier = advance();
 
-             while (index < last && esutils.code.isIdentifierPartES5(source.charCodeAt(index))) {
 
-                 identifier += advance();
 
-             }
 
-             return identifier;
 
-         }
 
-         function skipWhiteSpace(last) {
 
-             while (index < last && (esutils.code.isWhiteSpace(source.charCodeAt(index)) || esutils.code.isLineTerminator(source.charCodeAt(index)))) {
 
-                 advance();
 
-             }
 
-         }
 
-         function parseName(last, allowBrackets, allowNestedParams) {
 
-             var name = '',
 
-                 useBrackets,
 
-                 insideString;
 
-             skipWhiteSpace(last);
 
-             if (index >= last) {
 
-                 return null;
 
-             }
 
-             if (source.charCodeAt(index) === 0x5B  /* '[' */) {
 
-                 if (allowBrackets) {
 
-                     useBrackets = true;
 
-                     name = advance();
 
-                 } else {
 
-                     return null;
 
-                 }
 
-             }
 
-             name += scanIdentifier(last);
 
-             if (allowNestedParams) {
 
-                 if (source.charCodeAt(index) === 0x3A /* ':' */ && (
 
-                         name === 'module' ||
 
-                         name === 'external' ||
 
-                         name === 'event')) {
 
-                     name += advance();
 
-                     name += scanIdentifier(last);
 
-                 }
 
-                 if(source.charCodeAt(index) === 0x5B  /* '[' */ && source.charCodeAt(index + 1) === 0x5D  /* ']' */){
 
-                     name += advance();
 
-                     name += advance();
 
-                 }
 
-                 while (source.charCodeAt(index) === 0x2E  /* '.' */ ||
 
-                         source.charCodeAt(index) === 0x2F  /* '/' */ ||
 
-                         source.charCodeAt(index) === 0x23  /* '#' */ ||
 
-                         source.charCodeAt(index) === 0x2D  /* '-' */ ||
 
-                         source.charCodeAt(index) === 0x7E  /* '~' */) {
 
-                     name += advance();
 
-                     name += scanIdentifier(last);
 
-                 }
 
-             }
 
-             if (useBrackets) {
 
-                 skipWhiteSpace(last);
 
-                 // do we have a default value for this?
 
-                 if (source.charCodeAt(index) === 0x3D  /* '=' */) {
 
-                     // consume the '='' symbol
 
-                     name += advance();
 
-                     skipWhiteSpace(last);
 
-                     var ch;
 
-                     var bracketDepth = 1;
 
-                     // scan in the default value
 
-                     while (index < last) {
 
-                         ch = source.charCodeAt(index);
 
-                         if (esutils.code.isWhiteSpace(ch)) {
 
-                             if (!insideString) {
 
-                                 skipWhiteSpace(last);
 
-                                 ch = source.charCodeAt(index);
 
-                             }
 
-                         }
 
-                         if (ch === 0x27 /* ''' */) {
 
-                             if (!insideString) {
 
-                                 insideString = '\'';
 
-                             } else {
 
-                                 if (insideString === '\'') {
 
-                                     insideString = '';
 
-                                 }
 
-                             }
 
-                         }
 
-                         if (ch === 0x22 /* '"' */) {
 
-                             if (!insideString) {
 
-                                 insideString = '"';
 
-                             } else {
 
-                                 if (insideString === '"') {
 
-                                     insideString = '';
 
-                                 }
 
-                             }
 
-                         }
 
-                         if (ch === 0x5B /* '[' */) {
 
-                             bracketDepth++;
 
-                         } else if (ch === 0x5D  /* ']' */ &&
 
-                             --bracketDepth === 0) {
 
-                             break;
 
-                         }
 
-                         name += advance();
 
-                     }
 
-                 }
 
-                 skipWhiteSpace(last);
 
-                 if (index >= last || source.charCodeAt(index) !== 0x5D  /* ']' */) {
 
-                     // we never found a closing ']'
 
-                     return null;
 
-                 }
 
-                 // collect the last ']'
 
-                 name += advance();
 
-             }
 
-             return name;
 
-         }
 
-         function skipToTag() {
 
-             while (index < length && source.charCodeAt(index) !== 0x40  /* '@' */) {
 
-                 advance();
 
-             }
 
-             if (index >= length) {
 
-                 return false;
 
-             }
 
-             utility.assert(source.charCodeAt(index) === 0x40  /* '@' */);
 
-             return true;
 
-         }
 
-         function convertIndex(rangeIndex) {
 
-             if (source === originalSource) {
 
-                 return rangeIndex;
 
-             }
 
-             return convertUnwrappedCommentIndex(originalSource, rangeIndex);
 
-         }
 
-         function TagParser(options, title) {
 
-             this._options = options;
 
-             this._title = title.toLowerCase();
 
-             this._tag = {
 
-                 title: title,
 
-                 description: null
 
-             };
 
-             if (this._options.lineNumbers) {
 
-                 this._tag.lineNumber = lineNumber;
 
-             }
 
-             this._first = index - title.length - 1;
 
-             this._last = 0;
 
-             // space to save special information for title parsers.
 
-             this._extra = { };
 
-         }
 
-         // addError(err, ...)
 
-         TagParser.prototype.addError = function addError(errorText) {
 
-             var args = Array.prototype.slice.call(arguments, 1),
 
-                 msg = errorText.replace(
 
-                     /%(\d)/g,
 
-                     function (whole, index) {
 
-                         utility.assert(index < args.length, 'Message reference must be in range');
 
-                         return args[index];
 
-                     }
 
-                 );
 
-             if (!this._tag.errors) {
 
-                 this._tag.errors = [];
 
-             }
 
-             if (strict) {
 
-                 utility.throwError(msg);
 
-             }
 
-             this._tag.errors.push(msg);
 
-             return recoverable;
 
-         };
 
-         TagParser.prototype.parseType = function () {
 
-             // type required titles
 
-             if (isTypeParameterRequired(this._title)) {
 
-                 try {
 
-                     this._tag.type = parseType(this._title, this._last, this._options.range);
 
-                     if (!this._tag.type) {
 
-                         if (!isParamTitle(this._title) && !isReturnTitle(this._title)) {
 
-                             if (!this.addError('Missing or invalid tag type')) {
 
-                                 return false;
 
-                             }
 
-                         }
 
-                     }
 
-                 } catch (error) {
 
-                     this._tag.type = null;
 
-                     if (!this.addError(error.message)) {
 
-                         return false;
 
-                     }
 
-                 }
 
-             } else if (isAllowedType(this._title)) {
 
-                 // optional types
 
-                 try {
 
-                     this._tag.type = parseType(this._title, this._last, this._options.range);
 
-                 } catch (e) {
 
-                     //For optional types, lets drop the thrown error when we hit the end of the file
 
-                 }
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype._parseNamePath = function (optional) {
 
-             var name;
 
-             name = parseName(this._last, sloppy && isAllowedOptional(this._title), true);
 
-             if (!name) {
 
-                 if (!optional) {
 
-                     if (!this.addError('Missing or invalid tag name')) {
 
-                         return false;
 
-                     }
 
-                 }
 
-             }
 
-             this._tag.name = name;
 
-             return true;
 
-         };
 
-         TagParser.prototype.parseNamePath = function () {
 
-             return this._parseNamePath(false);
 
-         };
 
-         TagParser.prototype.parseNamePathOptional = function () {
 
-             return this._parseNamePath(true);
 
-         };
 
-         TagParser.prototype.parseName = function () {
 
-             var assign, name;
 
-             // param, property requires name
 
-             if (isAllowedName(this._title)) {
 
-                 this._tag.name = parseName(this._last, sloppy && isAllowedOptional(this._title), isAllowedNested(this._title));
 
-                 if (!this._tag.name) {
 
-                     if (!isNameParameterRequired(this._title)) {
 
-                         return true;
 
-                     }
 
-                     // it's possible the name has already been parsed but interpreted as a type
 
-                     // it's also possible this is a sloppy declaration, in which case it will be
 
-                     // fixed at the end
 
-                     if (isParamTitle(this._title) && this._tag.type && this._tag.type.name) {
 
-                         this._extra.name = this._tag.type;
 
-                         this._tag.name = this._tag.type.name;
 
-                         this._tag.type = null;
 
-                     } else {
 
-                         if (!this.addError('Missing or invalid tag name')) {
 
-                             return false;
 
-                         }
 
-                     }
 
-                 } else {
 
-                     name = this._tag.name;
 
-                     if (name.charAt(0) === '[' && name.charAt(name.length - 1) === ']') {
 
-                         // extract the default value if there is one
 
-                         // example: @param {string} [somebody=John Doe] description
 
-                         assign = name.substring(1, name.length - 1).split('=');
 
-                         if (assign.length > 1) {
 
-                             this._tag['default'] = assign.slice(1).join('=');
 
-                         }
 
-                         this._tag.name = assign[0];
 
-                         // convert to an optional type
 
-                         if (this._tag.type && this._tag.type.type !== 'OptionalType') {
 
-                             this._tag.type = {
 
-                                 type: 'OptionalType',
 
-                                 expression: this._tag.type
 
-                             };
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype.parseDescription = function parseDescription() {
 
-             var description = sliceSource(source, index, this._last).trim();
 
-             if (description) {
 
-                 if ((/^-\s+/).test(description)) {
 
-                     description = description.substring(2);
 
-                 }
 
-                 this._tag.description = description;
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype.parseCaption = function parseDescription() {
 
-             var description = sliceSource(source, index, this._last).trim();
 
-             var captionStartTag = '<caption>';
 
-             var captionEndTag = '</caption>';
 
-             var captionStart = description.indexOf(captionStartTag);
 
-             var captionEnd = description.indexOf(captionEndTag);
 
-             if (captionStart >= 0 && captionEnd >= 0) {
 
-                 this._tag.caption = description.substring(
 
-                     captionStart + captionStartTag.length, captionEnd).trim();
 
-                 this._tag.description = description.substring(captionEnd + captionEndTag.length).trim();
 
-             } else {
 
-                 this._tag.description = description;
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype.parseKind = function parseKind() {
 
-             var kind, kinds;
 
-             kinds = {
 
-                 'class': true,
 
-                 'constant': true,
 
-                 'event': true,
 
-                 'external': true,
 
-                 'file': true,
 
-                 'function': true,
 
-                 'member': true,
 
-                 'mixin': true,
 
-                 'module': true,
 
-                 'namespace': true,
 
-                 'typedef': true
 
-             };
 
-             kind = sliceSource(source, index, this._last).trim();
 
-             this._tag.kind = kind;
 
-             if (!hasOwnProperty(kinds, kind)) {
 
-                 if (!this.addError('Invalid kind name \'%0\'', kind)) {
 
-                     return false;
 
-                 }
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype.parseAccess = function parseAccess() {
 
-             var access;
 
-             access = sliceSource(source, index, this._last).trim();
 
-             this._tag.access = access;
 
-             if (access !== 'private' && access !== 'protected' && access !== 'public') {
 
-                 if (!this.addError('Invalid access name \'%0\'', access)) {
 
-                     return false;
 
-                 }
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype.parseThis = function parseThis() {
 
-             // this name may be a name expression (e.g. {foo.bar}),
 
-             // an union (e.g. {foo.bar|foo.baz}) or a name path (e.g. foo.bar)
 
-             var value = sliceSource(source, index, this._last).trim();
 
-             if (value && value.charAt(0) === '{') {
 
-                 var gotType = this.parseType();
 
-                 if (gotType && this._tag.type.type === 'NameExpression' || this._tag.type.type === 'UnionType') {
 
-                     this._tag.name = this._tag.type.name;
 
-                     return true;
 
-                 } else {
 
-                     return this.addError('Invalid name for this');
 
-                 }
 
-             } else {
 
-                 return this.parseNamePath();
 
-             }
 
-         };
 
-         TagParser.prototype.parseVariation = function parseVariation() {
 
-             var variation, text;
 
-             text = sliceSource(source, index, this._last).trim();
 
-             variation = parseFloat(text, 10);
 
-             this._tag.variation = variation;
 
-             if (isNaN(variation)) {
 
-                 if (!this.addError('Invalid variation \'%0\'', text)) {
 
-                     return false;
 
-                 }
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype.ensureEnd = function () {
 
-             var shouldBeEmpty = sliceSource(source, index, this._last).trim();
 
-             if (shouldBeEmpty) {
 
-                 if (!this.addError('Unknown content \'%0\'', shouldBeEmpty)) {
 
-                     return false;
 
-                 }
 
-             }
 
-             return true;
 
-         };
 
-         TagParser.prototype.epilogue = function epilogue() {
 
-             var description;
 
-             description = this._tag.description;
 
-             // un-fix potentially sloppy declaration
 
-             if (isAllowedOptional(this._title) && !this._tag.type && description && description.charAt(0) === '[') {
 
-                 this._tag.type = this._extra.name;
 
-                 if (!this._tag.name) {
 
-                     this._tag.name = undefined;
 
-                 }
 
-                 if (!sloppy) {
 
-                     if (!this.addError('Missing or invalid tag name')) {
 
-                         return false;
 
-                     }
 
-                 }
 
-             }
 
-             return true;
 
-         };
 
-         Rules = {
 
-             // http://usejsdoc.org/tags-access.html
 
-             'access': ['parseAccess'],
 
-             // http://usejsdoc.org/tags-alias.html
 
-             'alias': ['parseNamePath', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-augments.html
 
-             'augments': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-constructor.html
 
-             'constructor': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // Synonym: http://usejsdoc.org/tags-constructor.html
 
-             'class': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // Synonym: http://usejsdoc.org/tags-extends.html
 
-             'extends': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-example.html
 
-             'example': ['parseCaption'],
 
-             // http://usejsdoc.org/tags-deprecated.html
 
-             'deprecated': ['parseDescription'],
 
-             // http://usejsdoc.org/tags-global.html
 
-             'global': ['ensureEnd'],
 
-             // http://usejsdoc.org/tags-inner.html
 
-             'inner': ['ensureEnd'],
 
-             // http://usejsdoc.org/tags-instance.html
 
-             'instance': ['ensureEnd'],
 
-             // http://usejsdoc.org/tags-kind.html
 
-             'kind': ['parseKind'],
 
-             // http://usejsdoc.org/tags-mixes.html
 
-             'mixes': ['parseNamePath', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-mixin.html
 
-             'mixin': ['parseNamePathOptional', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-member.html
 
-             'member': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-method.html
 
-             'method': ['parseNamePathOptional', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-module.html
 
-             'module': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // Synonym: http://usejsdoc.org/tags-method.html
 
-             'func': ['parseNamePathOptional', 'ensureEnd'],
 
-             // Synonym: http://usejsdoc.org/tags-method.html
 
-             'function': ['parseNamePathOptional', 'ensureEnd'],
 
-             // Synonym: http://usejsdoc.org/tags-member.html
 
-             'var': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-name.html
 
-             'name': ['parseNamePath', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-namespace.html
 
-             'namespace': ['parseType', 'parseNamePathOptional', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-private.html
 
-             'private': ['parseType', 'parseDescription'],
 
-             // http://usejsdoc.org/tags-protected.html
 
-             'protected': ['parseType', 'parseDescription'],
 
-             // http://usejsdoc.org/tags-public.html
 
-             'public': ['parseType', 'parseDescription'],
 
-             // http://usejsdoc.org/tags-readonly.html
 
-             'readonly': ['ensureEnd'],
 
-             // http://usejsdoc.org/tags-requires.html
 
-             'requires': ['parseNamePath', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-since.html
 
-             'since': ['parseDescription'],
 
-             // http://usejsdoc.org/tags-static.html
 
-             'static': ['ensureEnd'],
 
-             // http://usejsdoc.org/tags-summary.html
 
-             'summary': ['parseDescription'],
 
-             // http://usejsdoc.org/tags-this.html
 
-             'this': ['parseThis', 'ensureEnd'],
 
-             // http://usejsdoc.org/tags-todo.html
 
-             'todo': ['parseDescription'],
 
-             // http://usejsdoc.org/tags-typedef.html
 
-             'typedef': ['parseType', 'parseNamePathOptional'],
 
-             // http://usejsdoc.org/tags-variation.html
 
-             'variation': ['parseVariation'],
 
-             // http://usejsdoc.org/tags-version.html
 
-             'version': ['parseDescription']
 
-         };
 
-         TagParser.prototype.parse = function parse() {
 
-             var i, iz, sequences, method;
 
-             // empty title
 
-             if (!this._title) {
 
-                 if (!this.addError('Missing or invalid title')) {
 
-                     return null;
 
-                 }
 
-             }
 
-             // Seek to content last index.
 
-             this._last = seekContent(this._title);
 
-             if (this._options.range) {
 
-                 this._tag.range = [this._first, source.slice(0, this._last).replace(/\s*$/, '').length].map(convertIndex);
 
-             }
 
-             if (hasOwnProperty(Rules, this._title)) {
 
-                 sequences = Rules[this._title];
 
-             } else {
 
-                 // default sequences
 
-                 sequences = ['parseType', 'parseName', 'parseDescription', 'epilogue'];
 
-             }
 
-             for (i = 0, iz = sequences.length; i < iz; ++i) {
 
-                 method = sequences[i];
 
-                 if (!this[method]()) {
 
-                     return null;
 
-                 }
 
-             }
 
-             return this._tag;
 
-         };
 
-         function parseTag(options) {
 
-             var title, parser, tag;
 
-             // skip to tag
 
-             if (!skipToTag()) {
 
-                 return null;
 
-             }
 
-             // scan title
 
-             title = scanTitle();
 
-             // construct tag parser
 
-             parser = new TagParser(options, title);
 
-             tag = parser.parse();
 
-             // Seek global index to end of this tag.
 
-             while (index < parser._last) {
 
-                 advance();
 
-             }
 
-             return tag;
 
-         }
 
-         //
 
-         // Parse JSDoc
 
-         //
 
-         function scanJSDocDescription(preserveWhitespace) {
 
-             var description = '', ch, atAllowed;
 
-             atAllowed = true;
 
-             while (index < length) {
 
-                 ch = source.charCodeAt(index);
 
-                 if (atAllowed && ch === 0x40  /* '@' */) {
 
-                     break;
 
-                 }
 
-                 if (esutils.code.isLineTerminator(ch)) {
 
-                     atAllowed = true;
 
-                 } else if (atAllowed && !esutils.code.isWhiteSpace(ch)) {
 
-                     atAllowed = false;
 
-                 }
 
-                 description += advance();
 
-             }
 
-             return preserveWhitespace ? description : description.trim();
 
-         }
 
-         function parse(comment, options) {
 
-             var tags = [], tag, description, interestingTags, i, iz;
 
-             if (options === undefined) {
 
-                 options = {};
 
-             }
 
-             if (typeof options.unwrap === 'boolean' && options.unwrap) {
 
-                 source = unwrapComment(comment);
 
-             } else {
 
-                 source = comment;
 
-             }
 
-             originalSource = comment;
 
-             // array of relevant tags
 
-             if (options.tags) {
 
-                 if (Array.isArray(options.tags)) {
 
-                     interestingTags = { };
 
-                     for (i = 0, iz = options.tags.length; i < iz; i++) {
 
-                         if (typeof options.tags[i] === 'string') {
 
-                             interestingTags[options.tags[i]] = true;
 
-                         } else {
 
-                             utility.throwError('Invalid "tags" parameter: ' + options.tags);
 
-                         }
 
-                     }
 
-                 } else {
 
-                     utility.throwError('Invalid "tags" parameter: ' + options.tags);
 
-                 }
 
-             }
 
-             length = source.length;
 
-             index = 0;
 
-             lineNumber = 0;
 
-             recoverable = options.recoverable;
 
-             sloppy = options.sloppy;
 
-             strict = options.strict;
 
-             description = scanJSDocDescription(options.preserveWhitespace);
 
-             while (true) {
 
-                 tag = parseTag(options);
 
-                 if (!tag) {
 
-                     break;
 
-                 }
 
-                 if (!interestingTags || interestingTags.hasOwnProperty(tag.title)) {
 
-                     tags.push(tag);
 
-                 }
 
-             }
 
-             return {
 
-                 description: description,
 
-                 tags: tags
 
-             };
 
-         }
 
-         exports.parse = parse;
 
-     }(jsdoc = {}));
 
-     exports.version = utility.VERSION;
 
-     exports.parse = jsdoc.parse;
 
-     exports.parseType = typed.parseType;
 
-     exports.parseParamType = typed.parseParamType;
 
-     exports.unwrapComment = unwrapComment;
 
-     exports.Syntax = shallowCopy(typed.Syntax);
 
-     exports.Error = utility.DoctrineError;
 
-     exports.type = {
 
-         Syntax: exports.Syntax,
 
-         parseType: typed.parseType,
 
-         parseParamType: typed.parseParamType,
 
-         stringify: typed.stringify
 
-     };
 
- }());
 
- /* vim: set sw=4 ts=4 et tw=80 : */
 
 
  |