Software zum Installieren eines Smart-Mirror Frameworks , zum Nutzen von hochschulrelevanten Informationen, auf einem Raspberry-Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

jsdoccomment.js 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * Obtained originally from {@link https://github.com/eslint/eslint/blob/master/lib/util/source-code.js#L313}.
  3. *
  4. * @license MIT
  5. */
  6. /**
  7. * Checks if the given token is a comment token or not.
  8. *
  9. * @param {Token} token - The token to check.
  10. * @returns {boolean} `true` if the token is a comment token.
  11. */
  12. const isCommentToken = (token) => {
  13. return token.type === 'Line' || token.type === 'Block' ||
  14. token.type === 'Shebang';
  15. };
  16. const getDecorator = (node) => {
  17. return node?.declaration?.decorators?.[0] || node?.decorators?.[0] ||
  18. node?.parent?.decorators?.[0];
  19. };
  20. /**
  21. * Check to see if its a ES6 export declaration.
  22. *
  23. * @param {ASTNode} astNode An AST node.
  24. * @returns {boolean} whether the given node represents an export declaration.
  25. * @private
  26. */
  27. const looksLikeExport = function (astNode) {
  28. return astNode.type === 'ExportDefaultDeclaration' ||
  29. astNode.type === 'ExportNamedDeclaration' ||
  30. astNode.type === 'ExportAllDeclaration' ||
  31. astNode.type === 'ExportSpecifier';
  32. };
  33. const getTSFunctionComment = function (astNode) {
  34. const {parent} = astNode;
  35. const grandparent = parent.parent;
  36. const greatGrandparent = grandparent.parent;
  37. const greatGreatGrandparent = greatGrandparent && greatGrandparent.parent;
  38. // istanbul ignore if
  39. if (parent.type !== 'TSTypeAnnotation') {
  40. return astNode;
  41. }
  42. switch (grandparent.type) {
  43. case 'ClassProperty':
  44. case 'TSDeclareFunction':
  45. case 'TSMethodSignature':
  46. case 'TSPropertySignature':
  47. return grandparent;
  48. case 'ArrowFunctionExpression':
  49. // istanbul ignore else
  50. if (
  51. greatGrandparent.type === 'VariableDeclarator'
  52. // && greatGreatGrandparent.parent.type === 'VariableDeclaration'
  53. ) {
  54. return greatGreatGrandparent.parent;
  55. }
  56. // istanbul ignore next
  57. return astNode;
  58. case 'FunctionExpression':
  59. // istanbul ignore else
  60. if (greatGrandparent.type === 'MethodDefinition') {
  61. return greatGrandparent;
  62. }
  63. // Fallthrough
  64. default:
  65. // istanbul ignore if
  66. if (grandparent.type !== 'Identifier') {
  67. // istanbul ignore next
  68. return astNode;
  69. }
  70. }
  71. // istanbul ignore next
  72. switch (greatGrandparent.type) {
  73. case 'ArrowFunctionExpression':
  74. // istanbul ignore else
  75. if (
  76. greatGreatGrandparent.type === 'VariableDeclarator' &&
  77. greatGreatGrandparent.parent.type === 'VariableDeclaration'
  78. ) {
  79. return greatGreatGrandparent.parent;
  80. }
  81. // istanbul ignore next
  82. return astNode;
  83. case 'FunctionDeclaration':
  84. return greatGrandparent;
  85. case 'VariableDeclarator':
  86. // istanbul ignore else
  87. if (greatGreatGrandparent.type === 'VariableDeclaration') {
  88. return greatGreatGrandparent;
  89. }
  90. // Fallthrough
  91. default:
  92. // istanbul ignore next
  93. return astNode;
  94. }
  95. };
  96. const invokedExpression = new Set(
  97. ['CallExpression', 'OptionalCallExpression', 'NewExpression']
  98. );
  99. const allowableCommentNode = new Set([
  100. 'VariableDeclaration',
  101. 'ExpressionStatement',
  102. 'MethodDefinition',
  103. 'Property',
  104. 'ObjectProperty',
  105. 'ClassProperty'
  106. ]);
  107. /**
  108. * Reduces the provided node to the appropriate node for evaluating
  109. * JSDoc comment status.
  110. *
  111. * @param {ASTNode} node An AST node.
  112. * @param {SourceCode} sourceCode The ESLint SourceCode.
  113. * @returns {ASTNode} The AST node that can be evaluated for appropriate
  114. * JSDoc comments.
  115. * @private
  116. */
  117. const getReducedASTNode = function (node, sourceCode) {
  118. let {parent} = node;
  119. switch (node.type) {
  120. case 'TSFunctionType':
  121. return getTSFunctionComment(node);
  122. case 'TSInterfaceDeclaration':
  123. case 'TSTypeAliasDeclaration':
  124. case 'TSEnumDeclaration':
  125. case 'ClassDeclaration':
  126. case 'FunctionDeclaration':
  127. return looksLikeExport(parent) ? parent : node;
  128. case 'TSDeclareFunction':
  129. case 'ClassExpression':
  130. case 'ObjectExpression':
  131. case 'ArrowFunctionExpression':
  132. case 'TSEmptyBodyFunctionExpression':
  133. case 'FunctionExpression':
  134. if (
  135. !invokedExpression.has(parent.type)
  136. ) {
  137. while (
  138. !sourceCode.getCommentsBefore(parent).length &&
  139. !(/Function/u).test(parent.type) &&
  140. !allowableCommentNode.has(parent.type)
  141. ) {
  142. ({parent} = parent);
  143. if (!parent) {
  144. break;
  145. }
  146. }
  147. if (parent && parent.type !== 'FunctionDeclaration' &&
  148. parent.type !== 'Program'
  149. ) {
  150. if (parent.parent && parent.parent.type === 'ExportNamedDeclaration') {
  151. return parent.parent;
  152. }
  153. return parent;
  154. }
  155. }
  156. return node;
  157. default:
  158. return node;
  159. }
  160. };
  161. /**
  162. * Checks for the presence of a JSDoc comment for the given node and returns it.
  163. *
  164. * @param {ASTNode} astNode The AST node to get the comment for.
  165. * @param {SourceCode} sourceCode
  166. * @param {{maxLines: Integer, minLines: Integer}} settings
  167. * @returns {Token|null} The Block comment token containing the JSDoc comment
  168. * for the given node or null if not found.
  169. * @private
  170. */
  171. const findJSDocComment = (astNode, sourceCode, settings) => {
  172. const {minLines, maxLines} = settings;
  173. let currentNode = astNode;
  174. let tokenBefore = null;
  175. while (currentNode) {
  176. const decorator = getDecorator(currentNode);
  177. if (decorator) {
  178. currentNode = decorator;
  179. }
  180. tokenBefore = sourceCode.getTokenBefore(
  181. currentNode, {includeComments: true}
  182. );
  183. if (!tokenBefore || !isCommentToken(tokenBefore)) {
  184. return null;
  185. }
  186. if (tokenBefore.type === 'Line') {
  187. currentNode = tokenBefore;
  188. continue;
  189. }
  190. break;
  191. }
  192. if (
  193. tokenBefore.type === 'Block' &&
  194. tokenBefore.value.charAt(0) === '*' &&
  195. currentNode.loc.start.line - tokenBefore.loc.end.line >= minLines &&
  196. currentNode.loc.start.line - tokenBefore.loc.end.line <= maxLines
  197. ) {
  198. return tokenBefore;
  199. }
  200. return null;
  201. };
  202. /**
  203. * Retrieves the JSDoc comment for a given node.
  204. *
  205. * @param {SourceCode} sourceCode The ESLint SourceCode
  206. * @param {ASTNode} node The AST node to get the comment for.
  207. * @param {PlainObject} settings The settings in context
  208. * @returns {Token|null} The Block comment token containing the JSDoc comment
  209. * for the given node or null if not found.
  210. * @public
  211. */
  212. const getJSDocComment = function (sourceCode, node, settings) {
  213. const reducedNode = getReducedASTNode(node, sourceCode);
  214. return findJSDocComment(reducedNode, sourceCode, settings);
  215. };
  216. export {
  217. getReducedASTNode, getJSDocComment, getDecorator, findJSDocComment
  218. };