Consolidate jsdoc node getters

They are now used both in getJSDocCommentsAndTagsWorker and in
geParameterSymbolFromJSDoc.
This commit is contained in:
Nathan Shively-Sanders 2017-10-19 14:12:56 -07:00
parent c2bbfafcbe
commit 97a6f14ca2

View File

@ -1538,6 +1538,34 @@ namespace ts {
return getJSDocCommentsAndTags(node);
}
export function getSourceOfAssignment(node: Node): Node {
return isExpressionStatement(node) &&
node.expression && isBinaryExpression(node.expression) &&
node.expression.operatorToken.kind === SyntaxKind.EqualsToken &&
node.expression.right;
}
export function getSingleInitializerOfVariableStatement(node: Node, child?: Node): Node {
return isVariableStatement(node) &&
node.declarationList.declarations.length > 0 &&
(!child || node.declarationList.declarations[0].initializer === child) &&
node.declarationList.declarations[0].initializer;
}
export function getSingleVariableOfVariableStatement(node: Node, child?: Node): Node {
return isVariableStatement(node) &&
node.declarationList.declarations.length > 0 &&
(!child || node.declarationList.declarations[0] === child) &&
node.declarationList.declarations[0];
}
export function getNestedModuleDeclaration(node: Node): Node {
return node.kind === SyntaxKind.ModuleDeclaration &&
(node as ModuleDeclaration).body &&
(node as ModuleDeclaration).body.kind === SyntaxKind.ModuleDeclaration &&
(node as ModuleDeclaration).body;
}
export function getJSDocCommentsAndTags(node: Node): (JSDoc | JSDocTag)[] {
let result: (JSDoc | JSDocTag)[] | undefined;
getJSDocCommentsAndTagsWorker(node);
@ -1551,35 +1579,15 @@ namespace ts {
// * @returns {number}
// */
// var x = function(name) { return name.length; }
const isInitializerOfVariableDeclarationInStatement =
isVariableLike(parent) &&
parent.initializer === node &&
parent.parent.parent.kind === SyntaxKind.VariableStatement;
const isVariableOfVariableDeclarationStatement = isVariableLike(node) &&
parent.parent.kind === SyntaxKind.VariableStatement;
const variableStatementNode =
isInitializerOfVariableDeclarationInStatement ? parent.parent.parent :
isVariableOfVariableDeclarationStatement ? parent.parent :
undefined;
if (variableStatementNode) {
getJSDocCommentsAndTagsWorker(variableStatementNode);
if (parent && (parent.kind === SyntaxKind.PropertyAssignment || getNestedModuleDeclaration(parent))) {
getJSDocCommentsAndTagsWorker(parent);
}
// Also recognize when the node is the RHS of an assignment expression
const isSourceOfAssignmentExpressionStatement =
parent && parent.parent &&
parent.kind === SyntaxKind.BinaryExpression &&
(parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken &&
parent.parent.kind === SyntaxKind.ExpressionStatement;
if (isSourceOfAssignmentExpressionStatement) {
if (parent && parent.parent &&
(getSingleVariableOfVariableStatement(parent.parent, node) || getSourceOfAssignment(parent.parent))) {
getJSDocCommentsAndTagsWorker(parent.parent);
}
const isModuleDeclaration = node.kind === SyntaxKind.ModuleDeclaration &&
parent && parent.kind === SyntaxKind.ModuleDeclaration;
const isPropertyAssignmentExpression = parent && parent.kind === SyntaxKind.PropertyAssignment;
if (isModuleDeclaration || isPropertyAssignmentExpression) {
getJSDocCommentsAndTagsWorker(parent);
if (parent && parent.parent && parent.parent.parent && getSingleInitializerOfVariableStatement(parent.parent.parent, node)) {
getJSDocCommentsAndTagsWorker(parent.parent.parent);
}
// Pull parameter comments from declaring function as well
@ -1606,24 +1614,16 @@ namespace ts {
return undefined;
}
const name = node.name.escapedText;
const decl = getJSDocHost(node);
let func: FunctionLike;
if (isExpressionStatement(decl) && isBinaryExpression(decl.expression) && isFunctionLike(decl.expression.right)) {
func = decl.expression.right;
const host = getJSDocHost(node);
const decl = getSourceOfAssignment(host) ||
getSingleInitializerOfVariableStatement(host) ||
getSingleVariableOfVariableStatement(host) ||
getNestedModuleDeclaration(host) ||
host;
if (decl && isFunctionLike(decl)) {
const parameter = find(decl.parameters, p => p.name.kind === SyntaxKind.Identifier && p.name.escapedText === name);
return parameter && parameter.symbol;
}
else if (isVariableStatement(decl) && decl.declarationList.declarations.length === 1 && isVariableDeclaration(decl.declarationList.declarations[0])
&& isFunctionLike(decl.declarationList.declarations[0].initializer)) {
func = decl.declarationList.declarations[0].initializer as FunctionLike;
}
else if (isFunctionLike(decl)) {
func = decl;
}
else {
return undefined;
}
const parameter = find(func.parameters, p =>
p.name.kind === SyntaxKind.Identifier && p.name.escapedText === name);
return parameter && parameter.symbol;
}
export function getJSDocHost(node: JSDocTag): HasJSDoc {