@quintaaa/eslint-plugin-starlims
Version:
Eslint plugin to parse and lint starlims form code successfully
256 lines (251 loc) • 9.52 kB
JavaScript
const xfdToHtmlFunctions = {
Convert: {
ToInt: [
() => 'parseInt',
(node) => getReplaceCalleeFixer(node, 'parseInt'),
],
ToInt32: [
() => 'parseInt',
(node) => getReplaceCalleeFixer(node, 'parseInt'),
],
ToDecimal: [
() => 'parseFloat',
(node) => getReplaceCalleeFixer(node, 'parseFloat'),
],
ToDouble: [
() => 'parseFloat',
(node) => getReplaceCalleeFixer(node, 'parseFloat'),
],
},
lims: {
ConvertToInt32: [
() => 'parseInt',
(node) => getReplaceCalleeFixer(node, 'parseInt'),
],
ConvertToDouble: [
() => 'parseFloat',
(node) => getReplaceCalleeFixer(node, 'parseFloat'),
],
ConvertToString: [
(node, context) => {
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
return `${arg0}.toString()`;
},
(node, context) => (fixer) => {
const fixes = [];
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
fixes.push(fixer.replaceText(node.callee, `${arg0}.toString`));
fixes.push(
fixer.replaceTextRange(
[
node.arguments[0].range[0],
node.arguments[0].range[1],
],
''
)
);
return fixes;
},
],
AAdd: [
(node, context) => {
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
const otherArgs = node.arguments
.slice(1)
.map((a) => context.getSourceCode().getText(a))
.join(', ');
return `${arg0}.push(${otherArgs})`;
},
(node, context) => (fixer) => {
const left = node.parent.left
? context.getSourceCode().getText(node.parent.left)
: '';
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
if (node.parent?.type !== 'AssignmentExpression') return null;
if (arg0 !== left) return null;
const otherArgs = node.arguments
.slice(1)
.map((a) => context.getSourceCode().getText(a))
.join(', ');
return fixer.replaceText(
node.parent,
`${arg0}.push(${otherArgs})`
);
},
],
AScan: [
(node, context) => {
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
const arg1 = node.arguments[1]
? context.getSourceCode().getText(node.arguments[1])
: '';
return `${arg0}.indexOf(${arg1})`;
},
(node, context) => (fixer) => {
const fixes = [];
const firstArgument = node.arguments[0];
const secondArgument = node.arguments[1];
const firstArgText = firstArgument
? context.getSourceCode().getText(firstArgument)
: '';
if (!secondArgument)
return fixer.replaceText(node, `${firstArgText}.indexOf()`);
fixes.push(
fixer.replaceText(node.callee, `${firstArgText}.indexOf`)
);
fixes.push(
fixer.replaceTextRange(
[firstArgument.range[0], secondArgument.range[0]],
''
)
);
return fixes;
},
],
Len: [
(node, context) =>
`${context.getSourceCode().getText(node.arguments[0])}.length`,
(node, context) => (fixer) => {
const firstArgument = node.arguments[0];
return fixer.replaceText(
node,
`${context.getSourceCode().getText(firstArgument)}.length`
);
},
],
JsonParse: [
(node, context) => {
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
return `JSON.parse(${arg0})`;
},
(node) => getReplaceCalleeFixer(node, 'JSON.parse'),
],
FromJson: [
(node, context) => {
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
return `JSON.parse(${arg0})`;
},
(node) => getReplaceCalleeFixer(node, 'JSON.parse'),
],
ExtractCol: [
(node, context) => {
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
const arg1 = node.arguments[1]
? context.getSourceCode().getText(node.arguments[1])
: '';
return node.arguments[0]
? `${arg0}.map(e => e[${arg1 || 'COL_NUMBER'}])`
: 'Array.map';
},
(node, context) => (fixer) => {
const fixes = [];
if (!node.arguments[0]) return null;
const arg0 = node.arguments[0]
? context.getSourceCode().getText(node.arguments[0])
: '';
const arg1 = node.arguments[1]
? context.getSourceCode().getText(node.arguments[1])
: '';
fixes.push(fixer.replaceText(node.callee, `${arg0}.map`));
fixes.push(
fixer.replaceTextRange(
[
node.arguments[0].range[0],
node.arguments[1]?.range[1] ??
node.arguments[0].range[1],
],
`e => e[${arg1 || 'COL_NUMBER'}]`
)
);
return fixes;
},
],
},
Int32: {
Parse: [
() => 'parseInt',
(node) => getReplaceCalleeFixer(node, 'parseInt'),
],
},
System: {
Diagnostics: {
Process: {
Start: [
() =>
'window.open (only to open a new page, otherwise you need an alternative solution)',
(node) => getReplaceCalleeFixer(node, 'window.open'),
],
},
},
},
int: [() => 'parseInt', (node) => getReplaceCalleeFixer(node, 'parseInt')],
};
module.exports = {
meta: {
type: 'problem',
docs: {
description:
'Find XFD functions that have not been converted to HTML',
recommended: true,
},
fixable: 'whitespace',
},
create(context) {
return {
CallExpression(node) {
const replacement = findReplacement(
node.callee,
xfdToHtmlFunctions
);
if (!replacement) return;
const fixerFunction = replacement[1](node, context);
context.report({
node,
message: `This function is a legacy function, in HTML you should use '{{ replacement }}'.`,
data: {
replacement: replacement[0](node, context),
},
fix: fixerFunction,
});
},
};
},
};
function findReplacement(node, functionReplacementObject) {
if (!functionReplacementObject) return;
if (Array.isArray(functionReplacementObject[node.name]))
return functionReplacementObject[node.name];
if (node.type === 'Identifier') return functionReplacementObject[node.name];
if (node.object.type === 'Identifier')
return findReplacement(
node.property,
functionReplacementObject[node.object.name]
);
if (node.object.type === 'MemberExpression')
return findReplacement(
node.property,
findReplacement(node.object, functionReplacementObject)
);
}
function fixSimpleReplace(fixer, node, replacement) {
return fixer.replaceText(node, replacement);
}
function getReplaceCalleeFixer(node, replacement) {
return (fixer) => fixSimpleReplace(fixer, node.callee, replacement);
}