Skip to content

Commit

Permalink
Refactor to use simple selectors (#2124)
Browse files Browse the repository at this point in the history
  • Loading branch information
fisker authored May 17, 2023
1 parent e761153 commit e6a8ff4
Show file tree
Hide file tree
Showing 5 changed files with 647 additions and 579 deletions.
126 changes: 68 additions & 58 deletions rules/no-process-exit.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
'use strict';
const {methodCallSelector} = require('./selectors/index.js');
const {isStaticRequire} = require('./ast/index.js');
const {isStaticRequire, isMethodCall} = require('./ast/index.js');

const MESSAGE_ID = 'no-process-exit';
const messages = {
[MESSAGE_ID]: 'Only use `process.exit()` in CLI apps. Throw an error instead.',
};

const processOnOrOnceCallSelector = methodCallSelector({
object: 'process',
methods: ['on', 'once'],
minimumArguments: 1,
});
const processExitCallSelector = methodCallSelector({
object: 'process',
method: 'exit',
});

/** @param {import('eslint').Rule.RuleContext} context */
const create = context => {
const startsWithHashBang = context.sourceCode.lines[0].indexOf('#!') === 0;
Expand All @@ -31,53 +20,74 @@ const create = context => {
let requiredWorkerThreadsModule = false;
const problemNodes = [];

return {
CallExpression(callExpression) {
// `require('worker_threads')`
if (
isStaticRequire(callExpression)
// TODO: Support `node:worker_threads`
&& callExpression.arguments[0].value === 'worker_threads'
) {
requiredWorkerThreadsModule = true;
}
},
ImportDeclaration(importDeclaration) {
// `import workerThreads from 'worker_threads'`
if (
importDeclaration.source.type === 'Literal'
// TODO: Support `node:worker_threads`
&& importDeclaration.source.value === 'worker_threads'
) {
requiredWorkerThreadsModule = true;
}
},
// Check `process.on` / `process.once` call
[processOnOrOnceCallSelector](node) {
// `require('worker_threads')`
context.on('CallExpression', callExpression => {
if (
isStaticRequire(callExpression)
// TODO: Support `node:worker_threads`
&& callExpression.arguments[0].value === 'worker_threads'
) {
requiredWorkerThreadsModule = true;
}
});

// `import workerThreads from 'worker_threads'`
context.on('ImportDeclaration', importDeclaration => {
if (
importDeclaration.source.type === 'Literal'
// TODO: Support `node:worker_threads`
&& importDeclaration.source.value === 'worker_threads'
) {
requiredWorkerThreadsModule = true;
}
});

// Check `process.on` / `process.once` call
context.on('CallExpression', node => {
if (isMethodCall(node, {
object: 'process',
methods: ['on', 'once'],
minimumArguments: 1,
optionalCall: false,
optionalMember: false,
})) {
processEventHandler = node;
},
// Check `process.exit` call
[processExitCallSelector](node) {
if (!processEventHandler) {
problemNodes.push(node);
}
},
'CallExpression:exit'(node) {
if (node === processEventHandler) {
processEventHandler = undefined;
}
},
* 'Program:exit'() {
if (!requiredWorkerThreadsModule) {
for (const node of problemNodes) {
yield {
node,
messageId: MESSAGE_ID,
};
}
}
},
};
}
});

// Check `process.exit` call
context.on('CallExpression', node => {
if (
!processEventHandler
&& isMethodCall(node, {
object: 'process',
method: 'exit',
optionalCall: false,
optionalMember: false,
})
) {
problemNodes.push(node);
}
});

context.on('CallExpression:exit', node => {
if (node === processEventHandler) {
processEventHandler = undefined;
}
});

context.on('Program:exit', function * () {
if (requiredWorkerThreadsModule) {
return;
}

for (const node of problemNodes) {
yield {
node,
messageId: MESSAGE_ID,
};
}
});
};

/** @type {import('eslint').Rule.RuleModule} */
Expand Down
Loading

0 comments on commit e6a8ff4

Please sign in to comment.