@@ -6,16 +6,46 @@ const JSDocTypeTokenizer = new JSDocTokenizer({
66 range : true
77} ) ;
88
9+ /**
10+ * @param {ASTNode } node
11+ * @return {boolean }
12+ */
13+ function isClass ( node ) {
14+ return node . type === 'ClassDeclaration' || (
15+ (
16+ node . type === 'ExpressionStatement' &&
17+ node . expression . type === 'AssignmentExpression' &&
18+ node . expression . right . type === 'ClassExpression'
19+ ) ||
20+ (
21+ node . type === 'VariableDeclaration' &&
22+ node . declarations . length === 1 &&
23+ node . declarations [ 0 ] . init &&
24+ node . declarations [ 0 ] . init . type === 'ClassExpression'
25+ )
26+ ) ;
27+ }
28+
929/**
1030 * @param {ASTNode } node
1131 * @param {SourceCode } sourceCode
1232 * @return {boolean }
1333 */
1434function isEnumExpression ( node , sourceCode ) {
1535 return (
16- hasJSDocTags ( node , [ 'enum' ] , sourceCode ) &&
17- node . expression . type === 'AssignmentExpression' &&
18- node . expression . right . type === 'ObjectExpression' &&
36+ hasJSDocTags ( node , [ 'enum' ] , sourceCode ) && (
37+ (
38+ node . type === 'ExpressionStatement' &&
39+ node . expression . type === 'AssignmentExpression' &&
40+ node . expression . right . type === 'ObjectExpression'
41+ ) ||
42+ (
43+ node . type === 'VariableDeclaration' &&
44+ node . declarations . length === 1 &&
45+ node . declarations [ 0 ] . init &&
46+ node . declarations [ 0 ] . init . type === 'ObjectExpression'
47+ )
48+ ) &&
1949 node . parent . type === 'Program'
2050 ) ;
2151}
@@ -27,21 +57,33 @@ function isEnumExpression(node, sourceCode) {
2757 */
2858function isTypedefExpression ( node , sourceCode ) {
2959 return (
30- hasJSDocTags ( node , [ 'typedef' ] , sourceCode ) &&
31- node . expression . type === 'MemberExpression' &&
60+ hasJSDocTags ( node , [ 'typedef' ] , sourceCode ) && (
61+ (
62+ node . type === 'ExpressionStatement' &&
63+ node . expression . type === 'MemberExpression'
64+ ) ||
65+ (
66+ node . type === 'VariableDeclaration' &&
67+ node . declarations . length === 1 &&
68+ node . declarations [ 0 ] . init === null
69+ )
70+ ) &&
3271 node . parent . type === 'Program'
3372 ) ;
3473}
3574
3675/**
3776 * @param {ASTNode } node
3877 * @param {SourceCode } sourceCode
39- * @param {boolean= } isStatic
78+ * @param {{
79+ * isStatic: (boolean|undefined)
80+ * }= } options
4081 * @return {boolean }
4182 */
42- function isConstantExpression ( node , sourceCode , isStatic = true ) {
83+ function isConstantExpression ( node , sourceCode , { isStatic = true } = { } ) {
4384 return (
4485 hasJSDocTags ( node , [ 'const' ] , sourceCode ) &&
86+ node . type === 'ExpressionStatement' &&
4587 node . expression . type === 'AssignmentExpression' &&
4688 node . expression . left . property . type === 'Identifier' &&
4789 ( isStatic ? node . parent . type === 'Program' : true )
@@ -50,16 +92,26 @@ function isConstantExpression(node, sourceCode, isStatic = true) {
5092
5193/**
5294 * @param {ASTNode } node
95+ * @param {SourceCode } sourceCode
5396 * @return {boolean }
5497 */
55- function isClass ( node ) {
98+ function isPropExpression ( node , sourceCode ) {
99+ if ( node . type !== 'ExpressionStatement' ) {
100+ return false ;
101+ }
102+
103+ if ( ! / A s s i g n m e n t E x p r e s s i o n | M e m b e r E x p r e s s i o n / . test ( node . expression . type ) ) {
104+ return false ;
105+ }
106+
107+ const lhs = node . expression . type === 'AssignmentExpression' ?
108+ node . expression . left . object :
109+ node . expression . object ;
110+
56111 return (
57- node . type === 'ClassDeclaration' ||
58- (
59- node . type === 'ExpressionStatement' &&
60- node . expression . type === 'AssignmentExpression' &&
61- node . expression . right . type === 'ClassExpression'
62- )
112+ lhs &&
113+ lhs . type === 'ThisExpression' &&
114+ hasJSDocTags ( node , [ 'type' , 'const' ] , sourceCode )
63115 ) ;
64116}
65117
@@ -90,25 +142,60 @@ function isTypecast(node, sourceCode) {
90142}
91143
92144/**
93- * @param {ASTNode } propExpression
145+ * @param {ASTNode } classNode
94146 * @return {string }
95147 */
96- function resolvePropName ( propExpression ) {
97- return propExpression . expression . type === 'MemberExpression' ?
98- propExpression . expression . property . name :
99- propExpression . expression . left . property . name ;
148+ function resolveClassName ( classNode ) { // eslint-disable-line consistent-return
149+ switch ( classNode . type ) {
150+ case 'ExpressionStatement' :
151+ return classNode . expression . left . type === 'MemberExpression' ?
152+ classNode . expression . left . property . name :
153+ classNode . expression . left . name ;
154+
155+ case 'ClassDeclaration' :
156+ return classNode . id . name ;
157+
158+ case 'VariableDeclaration' :
159+ return classNode . declarations [ 0 ] . id . name ;
160+ }
100161}
101162
102163/**
103- * @param {ASTNode } classNode
164+ * @param {ASTNode } enumExpression
104165 * @return {string }
105166 */
106- function resolveClassName ( classNode ) {
107- return classNode . expression && classNode . expression . type === 'AssignmentExpression' ?
108- classNode . expression . left . type === 'MemberExpression' ?
109- classNode . expression . left . property . name :
110- classNode . expression . left . name :
111- classNode . id . name ;
167+ function resolveEnumName ( enumExpression ) {
168+ return enumExpression . type === 'ExpressionStatement' ?
169+ enumExpression . expression . left . property . name :
170+ enumExpression . declarations [ 0 ] . id . name ;
171+ }
172+
173+ /**
174+ * @param {ASTNode } typedefExpression
175+ * @return {string }
176+ */
177+ function resolveTypedefName ( typedefExpression ) {
178+ return typedefExpression . type === 'ExpressionStatement' ?
179+ typedefExpression . expression . property . name :
180+ typedefExpression . declarations [ 0 ] . id . name ;
181+ }
182+
183+ /**
184+ * @param {ASTNode } constantExpression
185+ * @return {string }
186+ */
187+ function resolveConstantName ( constantExpression ) {
188+ return constantExpression . expression . left . property . name ;
189+ }
190+
191+ /**
192+ * @param {ASTNode } propExpression
193+ * @return {?string }
194+ */
195+ function resolvePropName ( propExpression ) {
196+ return propExpression . expression . type === 'MemberExpression' ?
197+ propExpression . expression . property . name :
198+ propExpression . expression . left . property . name ;
112199}
113200
114201/**
@@ -157,71 +244,7 @@ function getPropsFromClassConstructor(methodDefinition, sourceCode) {
157244 return [ ] ;
158245 }
159246
160- return methodDefinition . value . body . body . filter ( ( bodyChildNode ) => {
161- if ( bodyChildNode . type !== 'ExpressionStatement' ) {
162- return false ;
163- }
164-
165- const leftPart = bodyChildNode . expression . type === 'AssignmentExpression' ?
166- bodyChildNode . expression . left . object :
167- bodyChildNode . expression . object ;
168-
169- return (
170- leftPart &&
171- leftPart . type === 'ThisExpression' &&
172- hasJSDocTags ( bodyChildNode , [ 'type' , 'const' ] , sourceCode )
173- ) ;
174- } ) ;
175- }
176-
177- /**
178- * @param {ASTNode } memberExpression
179- * @return {ASTNode }
180- */
181- function getMemberExpressionRootIdentifier ( memberExpression ) {
182- let object = memberExpression . object ;
183- while ( object . type !== 'Identifier' ) {
184- object = object . object ;
185- }
186-
187- return object ;
188- }
189-
190- /**
191- * @param {Array<ASTNode> } expressions
192- * @return {Object<string|symbol, Array<ASTNode>> }
193- */
194- function groupStaticExpressions ( expressions ) {
195- const noGroupKey = Symbol ( ) ;
196- const groupedStaticExpressions = expressions . reduce ( ( groups , staticExpression ) => {
197- switch ( staticExpression . expression . type ) {
198- case 'Identifier' :
199- groups [ noGroupKey ] . push ( staticExpression ) ;
200-
201- break ;
202-
203- case 'MemberExpression' :
204- case 'AssignmentExpression' :
205- const rootIdentifier = getMemberExpressionRootIdentifier (
206- staticExpression . expression . type === 'AssignmentExpression' ?
207- staticExpression . expression . left :
208- staticExpression . expression
209- ) ;
210-
211- if ( ! groups [ rootIdentifier . name ] ) {
212- groups [ rootIdentifier . name ] = [ ] ;
213- }
214-
215- groups [ rootIdentifier . name ] . push ( staticExpression ) ;
216-
217- break ;
218- }
219-
220- return groups ;
221- } , { [ noGroupKey ] : [ ] } ) ;
222-
223- return Object . keys ( groupedStaticExpressions )
224- . map ( ( key ) => groupedStaticExpressions [ key ] ) ;
247+ return methodDefinition . value . body . body . filter ( ( node ) => isPropExpression ( node , sourceCode ) ) ;
225248}
226249
227250/**
@@ -408,17 +431,13 @@ function getJSDocTokenAfter(tokens, targetToken) {
408431 * @param {Array<JSDocTokenWithRange> } tokens
409432 * @param {JSDocTokenWithRange } token
410433 * @param {{
411- * requiredType : (string|undefined),
412- * requiredValue : (string|undefined),
434+ * type : (string|undefined),
435+ * value : (string|undefined),
413436 * moveForward: (boolean|undefined)
414437 * }= } options
415438 * @return {?JSDocTokenWithRange }
416439 */
417- function findFirstNonWhitespaceSiblingToken ( tokens , token , {
418- requiredType,
419- requiredValue,
420- moveForward = true
421- } = { } ) {
440+ function findNonWhitespaceSiblingJSDocToken ( tokens , token , { type, value, moveForward = true } = { } ) {
422441 let currentToken = token ;
423442
424443 while ( currentToken ) {
@@ -435,8 +454,8 @@ function findFirstNonWhitespaceSiblingToken(tokens, token, {
435454 }
436455
437456 if (
438- ( ! requiredType || currentToken . type === requiredType ) &&
439- ( ! requiredValue || currentToken . value === requiredValue )
457+ ( ! type || currentToken . type === type ) &&
458+ ( ! value || currentToken . value === value )
440459 ) {
441460 return currentToken ;
442461 }
@@ -546,16 +565,19 @@ function traverseJSDocType(type, callback) {
546565}
547566
548567module . exports = {
568+ isClass,
549569 isEnumExpression,
550570 isTypedefExpression,
551571 isConstantExpression,
552- isClass ,
572+ isPropExpression ,
553573 isTypecast,
554574 resolvePropName,
555575 resolveClassName,
576+ resolveEnumName,
577+ resolveTypedefName,
578+ resolveConstantName,
556579 resolveParamNames,
557580 getPropsFromClassConstructor,
558- groupStaticExpressions,
559581 getJSDocComment,
560582 parseJSDoc,
561583 hasJSDocTags,
@@ -567,8 +589,8 @@ module.exports = {
567589 getJSDocSubtypeTokens,
568590 getJSDocTokenBefore,
569591 getJSDocTokenAfter,
570- findFirstNonWhitespaceSiblingToken,
571592 getScopeFromJSDoc,
572593 getStaticTypeFromJSDoc,
594+ findNonWhitespaceSiblingJSDocToken,
573595 traverseJSDocType
574596} ;
0 commit comments