Comparing version
@@ -5,4 +5,5 @@ "use strict"; | ||
const logger_1 = require("./logger"); | ||
const doclet_utils_1 = require("./doclet_utils"); | ||
const PropTree_1 = require("./PropTree"); | ||
const type_resolve_helpers_1 = require("./type_resolve_helpers"); | ||
const PropTree_1 = require("./PropTree"); | ||
const declareModifier = ts.createModifier(ts.SyntaxKind.DeclareKeyword); | ||
@@ -23,6 +24,6 @@ const constModifier = ts.createModifier(ts.SyntaxKind.ConstKeyword); | ||
function validateClassChildren(children) { | ||
return validateClassLikeChildren(children, ts.isClassElement, 'ClassElement'); | ||
validateClassLikeChildren(children, ts.isClassElement, 'ClassElement'); | ||
} | ||
function validateInterfaceChildren(children) { | ||
return validateClassLikeChildren(children, ts.isTypeElement, 'TypeElement'); | ||
validateClassLikeChildren(children, ts.isTypeElement, 'TypeElement'); | ||
} | ||
@@ -46,10 +47,98 @@ function validateModuleChildren(children) { | ||
} | ||
function formatMultilineComment(comment) { | ||
return comment.split('\n').join('\n * '); | ||
} | ||
function handlePropsComment(props, jsdocTagName) { | ||
return props.map((prop) => { | ||
if (prop.description) { | ||
let name; | ||
if (prop.optional) { | ||
if (prop.defaultvalue !== undefined) { | ||
name = `[${prop.name} = ${prop.defaultvalue}]`; | ||
} | ||
else { | ||
name = `[${prop.name}]`; | ||
} | ||
} | ||
else { | ||
name = prop.name; | ||
} | ||
const description = ` - ${formatMultilineComment(prop.description)}`; | ||
return `\n * @${jsdocTagName} ${name}${description}`; | ||
} | ||
return ''; | ||
}).filter((value) => value !== '').join(''); | ||
} | ||
function handleReturnsComment(doclet) { | ||
if (doclet_utils_1.isFunctionDoclet(doclet) && doclet.returns) { | ||
return doclet.returns.map((ret) => { | ||
if (ret.description) | ||
return `\n * @returns ${formatMultilineComment(ret.description)}`; | ||
return ''; | ||
}) | ||
.filter((value) => value !== '').join(''); | ||
} | ||
return ''; | ||
} | ||
function handleExamplesComment(doclet) { | ||
if (doclet.examples !== undefined) { | ||
return doclet.examples.map((example) => { | ||
return `\n * @example | ||
* ${formatMultilineComment(example)}`; | ||
}) | ||
.join(''); | ||
} | ||
return ''; | ||
} | ||
function handleParamsComment(doclet) { | ||
if ((doclet_utils_1.isClassDoclet(doclet) | ||
|| doclet_utils_1.isFileDoclet(doclet) | ||
|| doclet_utils_1.isEventDoclet(doclet) | ||
|| doclet_utils_1.isFunctionDoclet(doclet) | ||
|| doclet_utils_1.isTypedefDoclet(doclet)) | ||
&& doclet.params) { | ||
return handlePropsComment(doclet.params, 'param'); | ||
} | ||
return ''; | ||
} | ||
function handlePropertiesComment(doclet) { | ||
if (!doclet_utils_1.isEnumDoclet(doclet) && doclet.properties) { | ||
return handlePropsComment(doclet.properties, 'property'); | ||
} | ||
return ''; | ||
} | ||
function handleComment(doclet, node) { | ||
if (doclet.comment && doclet.comment.length > 4) { | ||
let comment = doclet.comment; | ||
comment = comment.substring(2, doclet.comment.length - 2); | ||
comment = comment.replace(/[ \t]+\*/g, ' *'); | ||
comment = comment.trim() + '\n '; | ||
const kind = ts.SyntaxKind.MultiLineCommentTrivia; | ||
ts.addSyntheticLeadingComment(node, kind, comment, true); | ||
let description = ''; | ||
if (doclet.description) { | ||
description = `\n * ${formatMultilineComment(doclet.description)}`; | ||
} | ||
else if (doclet_utils_1.isClassDoclet(doclet) && doclet.classdesc) { | ||
description = `\n * ${formatMultilineComment(doclet.classdesc)}`; | ||
} | ||
const examples = handleExamplesComment(doclet); | ||
const properties = handlePropertiesComment(doclet); | ||
const params = handleParamsComment(doclet); | ||
const returns = handleReturnsComment(doclet); | ||
if (doclet_utils_1.isEnumDoclet(doclet)) { | ||
if (!ts.isEnumDeclaration(node)) { | ||
logger_1.warn(`Node is not an enum declaration, even though the doclet is. This is likely a tsd-jsdoc bug.`); | ||
return node; | ||
} | ||
if (doclet.properties) { | ||
const enumProperties = doclet.properties; | ||
const enumMembers = node.members; | ||
for (let index = 0; index < enumProperties.length; index++) { | ||
const enumProperty = enumProperties[index]; | ||
const enumMember = enumMembers[index]; | ||
handleComment(enumProperty, enumMember); | ||
} | ||
} | ||
} | ||
if (description || examples || properties || params || returns) { | ||
let comment = `*${description}${examples}${properties}${params}${returns} | ||
`; | ||
const kind = ts.SyntaxKind.MultiLineCommentTrivia; | ||
ts.addSyntheticLeadingComment(node, kind, comment, true); | ||
} | ||
} | ||
@@ -75,3 +164,3 @@ return node; | ||
const opt = node.prop.optional ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined; | ||
const t = node.children.length ? type_resolve_helpers_1.createTypeLiteral(node.children) : type_resolve_helpers_1.resolveType(node.prop.type); | ||
const t = node.children.length ? type_resolve_helpers_1.createTypeLiteral(node.children, node) : type_resolve_helpers_1.resolveType(node.prop.type); | ||
const property = ts.createProperty(undefined, undefined, node.name, opt, t, undefined); | ||
@@ -78,0 +167,0 @@ if (node.prop.description) { |
@@ -6,16 +6,8 @@ "use strict"; | ||
const assert_never_1 = require("./assert_never"); | ||
const doclet_utils_1 = require("./doclet_utils"); | ||
const create_helpers_1 = require("./create_helpers"); | ||
function isClassLike(doclet) { | ||
return doclet.kind === 'class' || doclet.kind === 'interface' || doclet.kind === 'mixin'; | ||
} | ||
function isModuleLike(doclet) { | ||
return doclet.kind === 'module' || doclet.kind === 'namespace'; | ||
} | ||
function isEnum(doclet) { | ||
return (doclet.kind === 'member' || doclet.kind === 'constant') && doclet.isEnum; | ||
} | ||
function shouldMoveOutOfClass(doclet) { | ||
return isClassLike(doclet) | ||
|| isModuleLike(doclet) | ||
|| isEnum(doclet) | ||
return doclet_utils_1.isClassDoclet(doclet) | ||
|| doclet_utils_1.isNamespaceDoclet(doclet) | ||
|| doclet_utils_1.isEnumDoclet(doclet) | ||
|| doclet.kind === 'typedef'; | ||
@@ -117,3 +109,3 @@ } | ||
} | ||
const isParentClassLike = isClassLike(parent.doclet); | ||
const isParentClassLike = doclet_utils_1.isClassDoclet(parent.doclet); | ||
if (isParentClassLike && shouldMoveOutOfClass(doclet)) { | ||
@@ -128,7 +120,7 @@ const mod = this._getOrCreateClassNamespace(parent); | ||
else { | ||
const isObjModuleLike = isModuleLike(doclet); | ||
const isParentModuleLike = isModuleLike(parent.doclet); | ||
const isObjModuleLike = doclet_utils_1.isNamespaceDoclet(doclet); | ||
const isParentModuleLike = doclet_utils_1.isNamespaceDoclet(parent.doclet); | ||
if (isObjModuleLike && isParentModuleLike) | ||
obj.isNested = true; | ||
const isParentEnum = isEnum(parent.doclet); | ||
const isParentEnum = doclet_utils_1.isEnumDoclet(parent.doclet); | ||
if (!isParentEnum) { | ||
@@ -135,0 +127,0 @@ if (interfaceMerge) |
@@ -12,3 +12,8 @@ "use strict"; | ||
return; | ||
console.warn(`${header} ${msg}`); | ||
let prefix = header; | ||
if (data && data.meta) { | ||
const meta = data.meta; | ||
prefix = `${prefix} ${meta.filename}:${meta.lineno}:${meta.columnno}`; | ||
} | ||
console.warn(`${prefix} ${msg}`); | ||
if (isVerbose && arguments.length > 1) { | ||
@@ -15,0 +20,0 @@ console.warn(data); |
@@ -33,3 +33,6 @@ "use strict"; | ||
parts.pop(); | ||
const parentName = parts.join('.'); | ||
let parentName = parts.join('.'); | ||
if (parentName.endsWith('[]')) { | ||
parentName = parentName.substring(0, parentName.length - '[]'.length); | ||
} | ||
const parent = this.nodes[parentName]; | ||
@@ -36,0 +39,0 @@ if (!parent) { |
@@ -10,3 +10,3 @@ "use strict"; | ||
data({ undocumented: true }).remove(); | ||
const docs = data().get(); | ||
const docs = data().get().filter(d => !d.inherited || d.overrides); | ||
logger_1.setVerbose(!!opts.verbose); | ||
@@ -13,0 +13,0 @@ const emitter = new Emitter_1.Emitter(opts); |
@@ -433,18 +433,22 @@ "use strict"; | ||
exports.resolveTypeLiteral = resolveTypeLiteral; | ||
function createTypeLiteral(nodes) { | ||
function createTypeLiteral(children, parent) { | ||
const members = []; | ||
for (let i = 0; i < nodes.length; ++i) { | ||
const node = nodes[i]; | ||
for (let i = 0; i < children.length; ++i) { | ||
const node = children[i]; | ||
const opt = node.prop.optional ? ts.createToken(ts.SyntaxKind.QuestionToken) : undefined; | ||
const t = node.children.length ? createTypeLiteral(node.children) : resolveType(node.prop.type); | ||
const t = node.children.length ? createTypeLiteral(node.children, node) : resolveType(node.prop.type); | ||
members.push(ts.createPropertySignature(undefined, node.name, opt, t, undefined)); | ||
} | ||
return ts.createTypeLiteralNode(members); | ||
let node = ts.createTypeLiteralNode(members); | ||
if (parent) { | ||
const names = parent.prop.type.names; | ||
if (names.length === 1 && names[0].toLowerCase() === 'array.<object>') { | ||
node = ts.createArrayTypeNode(node); | ||
} | ||
} | ||
return node; | ||
} | ||
exports.createTypeLiteral = createTypeLiteral; | ||
function createFunctionParams(doclet) { | ||
if (!doclet.params || !doclet.params.length) | ||
return []; | ||
const params = []; | ||
const tree = new PropTree_1.PropTree(doclet.params); | ||
if ((doclet.kind === 'function' || doclet.kind === 'typedef') && doclet.this) { | ||
@@ -454,2 +458,5 @@ const type = resolveType({ names: [doclet.this] }, doclet); | ||
} | ||
if (!doclet.params || !doclet.params.length) | ||
return params; | ||
const tree = new PropTree_1.PropTree(doclet.params); | ||
for (let i = 0; i < tree.roots.length; ++i) { | ||
@@ -459,3 +466,3 @@ const node = tree.roots[i]; | ||
const dots = resolveVariableParameter(node.prop); | ||
let type = node.children.length ? createTypeLiteral(node.children) : resolveType(node.prop.type); | ||
let type = node.children.length ? createTypeLiteral(node.children, node) : resolveType(node.prop.type); | ||
if (dots) { | ||
@@ -462,0 +469,0 @@ type = ts.createArrayTypeNode(type); |
{ | ||
"name": "tsd-jsdoc", | ||
"version": "2.4.0", | ||
"version": "2.5.0", | ||
"description": "Compiles JSDoc annotated javascript into a Typescript Declaration File (.d.ts).", | ||
@@ -16,3 +16,3 @@ "main": "dist/publish.js", | ||
"prepare": "npm run build", | ||
"test": "mocha --ui tdd -r ts-node/register test/specs/**.ts" | ||
"test": "npm run build && mocha --ui tdd -r ts-node/register test/specs/**.ts" | ||
}, | ||
@@ -29,9 +29,10 @@ "files": [ | ||
"chai": "^4.2.0", | ||
"jsdoc": "^3.5.5", | ||
"jsdoc-api": "^4.0.3", | ||
"jsdoc": "^3.6.3", | ||
"jsdoc-api": "^5.0.3", | ||
"mocha": "^5.2.0", | ||
"object-to-spawn-args": "^2.0.0", | ||
"ts-node": "^7.0.1" | ||
}, | ||
"peerDependencies": { | ||
"jsdoc": "^3.5.5" | ||
"jsdoc": "^3.6.3" | ||
}, | ||
@@ -38,0 +39,0 @@ "dependencies": { |
@@ -37,2 +37,13 @@ # tsd-jsdoc | ||
If you want to use jsdoc/closure tag `@template`, you also need to specify this module as a plugin, like so: | ||
```json | ||
{ | ||
"plugins": [ "./node_modules/tsd-jsdoc/dist/plugin" ], | ||
"opts": { | ||
"template": "./node_modules/tsd-jsdoc/dist" | ||
} | ||
} | ||
``` | ||
## Validation | ||
@@ -39,0 +50,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
106664
10.95%23
21.05%1219
13.61%117
10.38%9
12.5%