function jsdoc( source, node ) {
	var comment;
	var parent;
	var type;

	parent = node.parent;
	type = node.type;

	if ( type === 'ClassDeclaration' || type === 'FunctionDeclaration' ) {
		return findToken( node );
	}
	if ( type === 'VariableDeclaration' || type === 'ExpressionStatement' ) {
		comment = findToken( node );
		if ( comment && startsWith( comment.value, '*' ) ) {
			return comment;
		}
		return null;
	}
	if ( type === 'ClassExpression' ) {
		return findToken( parent.parent );
	}
	if ( type === 'ArrowFunctionExpression' || type === 'FunctionExpression' ) {
		if ( parent.type !== 'CallExpression' && parent.type !== 'NewExpression' ) {
			while (
				!source.getCommentsBefore( parent ).length &&
				!RE_FUNCTION.test( parent.type ) &&
				parent.type !== 'MethodDefinition' &&
				parent.type !== 'Property'
			) {
				parent = parent.parent;
				if ( !parent ) {
					break;
				}
			}
			if (
				parent &&
				parent.type !== 'FunctionDeclaration' &&
				parent.type !== 'Program'
			) {
				return findToken( parent );
			}
		}
		return findToken( node );
	}
	return null;

	/**
	* Checks for a JSDoc comment associated with a given node and, if found, returns the comment.
	*
	* @private
	* @param {ASTNode} node - AST node
	* @returns {(Token|null)} block comment token containing a JSDoc comment or null
	*/
	function findToken( node ) {
		var prev;
		var opts;
		var incr;

		opts = {
			'includeComments': true
		};
		prev = source.getTokenBefore( node, opts );
		incr = 1;
		if (
			prev &&
			isCommentToken( prev ) &&
			prev.type === 'Line'
		) {
			opts.skip = 1;
			prev = source.getTokenBefore( node, opts );
			incr += 3;
		}
		if (
			prev &&
			isCommentToken( prev ) &&
			prev.type === 'Block' &&
			prev.value.charAt( 0 ) === '*' &&
			node.loc.start.line-prev.loc.end.line <= incr
		) {
			return prev;
		}
		return null;
	}
}
Retrieves the JSDoc comment associated with a given AST node.

@param {Source} source - source code
@param {ASTNode} node - AST node
@returns {(Token|null)} block comment token containing a JSDoc comment or null