1818
1919import type { Rule } from 'eslint' ;
2020import type estree from 'estree' ;
21- import { generateMeta , getFullyQualifiedName } from '../helpers/index.js' ;
21+ import {
22+ generateMeta ,
23+ getFullyQualifiedName ,
24+ getUniqueWriteReference ,
25+ getVariableFromScope ,
26+ } from '../helpers/index.js' ;
2227import * as meta from './generated-meta.js' ;
2328
2429const templatingFqns : Set < string > = new Set ( [
@@ -41,7 +46,12 @@ export const rule: Rule.RuleModule = {
4146 const callExpression = node as estree . CallExpression ;
4247 const fqn = getFullyQualifiedName ( context , callExpression ) ;
4348
44- if ( fqn && templatingFqns . has ( fqn ) && isQuestionable ( callExpression ) ) {
49+ if (
50+ fqn &&
51+ templatingFqns . has ( fqn ) &&
52+ ! isCallingFunctionResult ( context , callExpression ) &&
53+ isQuestionable ( callExpression )
54+ ) {
4555 context . report ( {
4656 messageId : 'reviewDynamicTemplate' ,
4757 node : callExpression . callee ,
@@ -52,6 +62,27 @@ export const rule: Rule.RuleModule = {
5262 } ,
5363} ;
5464
65+ /**
66+ * Returns true when the callee is a variable holding the result of a prior call,
67+ * e.g. `const fn = pug.compile(tpl); fn(data);` — fn(data) is not a direct
68+ * templating call, so we should not flag it again.
69+ */
70+ function isCallingFunctionResult (
71+ context : Rule . RuleContext ,
72+ callExpression : estree . CallExpression ,
73+ ) : boolean {
74+ const callee = callExpression . callee ;
75+ if ( callee . type !== 'Identifier' ) {
76+ return false ;
77+ }
78+ const variable = getVariableFromScope ( context . sourceCode . getScope ( callee ) , callee . name ) ;
79+ if ( ! variable || variable . defs . some ( def => def . type === 'ImportBinding' ) ) {
80+ return false ;
81+ }
82+ const writeRef = getUniqueWriteReference ( variable ) ;
83+ return writeRef ?. type === 'CallExpression' ;
84+ }
85+
5586function isQuestionable ( node : estree . CallExpression , index = 0 ) : boolean {
5687 const args = node . arguments ;
5788 const templateString = args [ index ] as estree . Expression | estree . SpreadElement | undefined ;
0 commit comments