TelegramPWA/dev/eslint-multitab/lib/rules/must-update-global-after-await.js
2023-01-28 02:21:33 +01:00

109 lines
3.2 KiB
JavaScript

/**
* @fileoverview Must update global after await
* @author undrfined
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('eslint').Rule.RuleModule} */
// TODO This rule is not working properly
module.exports = {
meta: {
type: "problem",
docs: {
description: "Must update global after await",
recommended: false,
url: null,
},
fixable: null,
schema: [],
messages: {
mustUpdateGlobalAfterAwait: "Global is outdated because of await here -> {{before}}, use global = getGlobal() to update",
}
},
create(context) {
let hasAssignmentOnBlockLevel;
let blocks = 0;
let d;
let hasAwait = false;
let hasAwaitOnBlockLevel;
let assigned;
//----------------------------------------------------------------------
// Helpers
//----------------------------------------------------------------------
function endFunction() {
hasAwait = false;
assigned = undefined;
d = undefined;
hasAssignmentOnBlockLevel = undefined;
hasAwaitOnBlockLevel = undefined;
}
//----------------------------------------------------------------------
// Public
//----------------------------------------------------------------------
return {
'FunctionDeclaration:exit': endFunction,
'FunctionExpression:exit': endFunction,
'ArrowFunctionExpression:exit': endFunction,
'AwaitExpression:exit': (node) => {
if(!node) return;
hasAwait = true;
hasAwaitOnBlockLevel = blocks;
d = node;
},
'BlockStatement': () => {
blocks += 1;
},
'BlockStatement:exit': () => {
blocks -= 1;
if(hasAwaitOnBlockLevel && blocks === hasAwaitOnBlockLevel) {
hasAwaitOnBlockLevel = undefined;
}
},
'ReturnStatement:exit': (node) => {
if(hasAwait && hasAwaitOnBlockLevel && blocks === hasAwaitOnBlockLevel && node.parent.type === 'BlockExpression') {
endFunction();
}
},
'AssignmentExpression': (node) => {
if(node.left.type !== "Identifier" || node.left.name !== "global") return;
if(node.right.type !== "CallExpression" || node.right.callee.name !== "getGlobal") return;
if(hasAwaitOnBlockLevel && blocks === hasAwaitOnBlockLevel) {
hasAwait = false;
hasAwaitOnBlockLevel = undefined;
d = undefined;
} else {
hasAssignmentOnBlockLevel = blocks;
assigned = node;
}
},
Identifier: (node) => {
if(node.name !== "global") return;
if(node.parent === assigned) return;
if(hasAwait) {
if(hasAssignmentOnBlockLevel !== undefined && hasAssignmentOnBlockLevel <= blocks) {
endFunction();
return;
}
context.report({
node,
messageId: "mustUpdateGlobalAfterAwait",
data: {
before: d ? d.loc.start.line + ':' + d.loc.start.column : 'unknown'
},
})
}
},
"Program:exit": endFunction,
};
},
};