@@ -163,6 +163,7 @@ module.exports = createRule({
163163 /** @type {import('typescript').JSDocThrowsTag[] } */
164164 const comments = [ ] ;
165165 comments . push ( ...getJSDocThrowsTags ( calleeDeclaration ) ) ;
166+ throwsComments . set ( getNodeID ( callerDeclaration ) , comments ) ;
166167
167168 const calleeThrowsTypes = getJSDocThrowsTagTypes ( checker , calleeDeclaration ) ;
168169 for ( const type of calleeThrowsTypes ) {
@@ -194,8 +195,7 @@ module.exports = createRule({
194195 flattened
195196 . forEach ( t => metadata . set ( t , { pos : node . range [ 0 ] } ) ) ;
196197 }
197- } ;
198- throwsComments . set ( getNodeID ( callerDeclaration ) , comments ) ;
198+ }
199199 } ;
200200
201201 /**
@@ -204,7 +204,8 @@ module.exports = createRule({
204204 * @param {import('@typescript-eslint/utils').TSESTree.Node } node
205205 */
206206 const visitIterableNode = ( node ) => {
207- if ( isInHandledContext ( node ) ) return ;
207+ const iterableType = services . getTypeAtLocation ( node ) ;
208+ if ( ! isGeneratorLike ( iterableType ) ) return ;
208209
209210 const callerDeclaration = findClosestFunctionNode ( node ) ;
210211 if ( ! callerDeclaration ) return ;
@@ -227,16 +228,34 @@ module.exports = createRule({
227228
228229 if ( ! calleeDeclaration ) return ;
229230
231+ /** @type {import('typescript').JSDocThrowsTag[] } */
232+ const comments = [ ] ;
233+ comments . push ( ...getJSDocThrowsTags ( calleeDeclaration ) ) ;
234+ throwsComments . set ( getNodeID ( callerDeclaration ) , comments ) ;
235+
230236 const calleeThrowsTypes = getJSDocThrowsTagTypes ( checker , calleeDeclaration ) ;
231237 if ( ! calleeThrowsTypes . length ) return ;
232238
233239 for ( const type of calleeThrowsTypes ) {
234- const flattened = toFlattenedTypeArray ( [ type ] ) ;
240+ if ( isPromiseType ( services , type ) ) {
241+ if ( isInAsyncHandledContext ( sourceCode , node ) ) continue ;
235242
236- throwTypes . add ( callerDeclaration , flattened ) ;
243+ const flattened =
244+ toFlattenedTypeArray ( [ checker . getAwaitedType ( type ) ?? type ] ) ;
237245
238- flattened
239- . forEach ( t => metadata . set ( t , { pos : node . range [ 0 ] } ) ) ;
246+ rejectTypes . add ( callerDeclaration , flattened ) ;
247+
248+ flattened
249+ . forEach ( t => metadata . set ( t , { pos : node . range [ 0 ] } ) ) ;
250+ } else {
251+ if ( isInHandledContext ( node ) ) continue ;
252+ const flattened = toFlattenedTypeArray ( [ type ] ) ;
253+
254+ throwTypes . add ( callerDeclaration , flattened ) ;
255+
256+ flattened
257+ . forEach ( t => metadata . set ( t , { pos : node . range [ 0 ] } ) ) ;
258+ }
240259 }
241260 } ;
242261
@@ -721,57 +740,91 @@ module.exports = createRule({
721740 */
722741 /**
723742 * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of MDN }
743+ * @example
744+ * ```
745+ * for (const item of iterable) { ... }
746+ * // ^ this
747+ * ```
724748 */
725749 'ForOfStatement' ( node ) {
726- const iterableType = services . getTypeAtLocation ( node . right ) ;
727- if ( ! isGeneratorLike ( iterableType ) ) return ;
728-
729750 visitIterableNode ( node . right ) ;
730751 } ,
731752 /**
732753 * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax MDN }
754+ * @example
755+ * ```
756+ * [...iterable]
757+ * // ^ this
758+ * ```
733759 */
734760 'SpreadElement' ( node ) {
735- const iterableType = services . getTypeAtLocation ( node . argument ) ;
736- if ( ! isGeneratorLike ( iterableType ) ) return ;
737-
738761 visitIterableNode ( node . argument ) ;
739762 } ,
740763 /**
741764 * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from MDN }
742765 * @param {import('@typescript-eslint/utils').TSESTree.CallExpression } node
766+ * @example
767+ * ```
768+ * Array.from(iterable)
769+ * // ^ this
770+ * ```
743771 */
744772 'CallExpression:has(> MemberExpression[object.name="Array"][property.name="from"])' ( node ) {
745773 if ( node . arguments . length < 1 ) return ;
746774
747775 const [ firstArgumentNode ] = node . arguments ;
748- const iterableType = services . getTypeAtLocation ( firstArgumentNode ) ;
749- if ( ! isGeneratorLike ( iterableType ) ) return ;
776+
777+ visitIterableNode ( firstArgumentNode ) ;
778+ } ,
779+ /**
780+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync MDN }
781+ * @param {import('@typescript-eslint/utils').TSESTree.CallExpression } node
782+ * @example
783+ * ```
784+ * await Array.fromAsync(iterable)
785+ * // ^ this
786+ * ```
787+ */
788+ 'CallExpression:has(> MemberExpression[object.name="Array"][property.name="fromAsync"])' ( node ) {
789+ if ( node . arguments . length < 1 ) return ;
790+
791+ const [ firstArgumentNode ] = node . arguments ;
750792
751793 visitIterableNode ( firstArgumentNode ) ;
752794 } ,
753795 /**
754796 * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield* MDN }
755797 * @param {import('@typescript-eslint/utils').TSESTree.YieldExpression } node
798+ * @example
799+ * ```
800+ * function* gen() {
801+ * yield* iterable;
802+ * // ^ this
803+ * }
804+ * // or
805+ * async function* asyncGen() {
806+ * yield* iterable;
807+ * // ^ this
808+ * }
809+ * ```
756810 */
757811 'YieldExpression[delegate=true]' ( node ) {
758812 if ( ! node . argument ) return ;
759813
760- const iterableType = services . getTypeAtLocation ( node . argument ) ;
761- if ( ! isGeneratorLike ( iterableType ) ) return ;
762-
763814 visitIterableNode ( node . argument ) ;
764815 } ,
765816 /**
766817 * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next MDN }
767818 * @param {import('@typescript-eslint/utils').TSESTree.CallExpression } node
819+ * @example
820+ * ```
821+ * iterable.next();
822+ * // ^ this
823+ * ```
768824 */
769825 'CallExpression[callee.property.name="next"]' ( node ) {
770826 if ( node . callee . type !== AST_NODE_TYPES . MemberExpression ) return ;
771827
772- const iterableType = services . getTypeAtLocation ( node . callee . object ) ;
773- if ( ! isGeneratorLike ( iterableType ) ) return ;
774-
775828 visitIterableNode ( node . callee . object ) ;
776829 } ,
777830
0 commit comments