Skip to content

Instantly share code, notes, and snippets.

@mikaelbr
Last active February 26, 2021 08:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikaelbr/8c6deba7686d05f21a5de3ca4bc04a4b to your computer and use it in GitHub Desktop.
Save mikaelbr/8c6deba7686d05f21a5de3ca4bc04a4b to your computer and use it in GitHub Desktop.
module.exports = {
meta: {
type: 'problem',
fixable: 'code',
schema: [
{
type: 'object',
properties: {
translateFunctionIdentifier: {type: 'string'},
translateModulePrefix: {type: 'string'},
ignoreLocalImports: {
type: 'array',
items: {
type: 'string',
},
},
},
},
],
},
create: function (context) {
const [config] = context.options;
const toObjectKeys = (names) =>
names.reduce((obj, n) => ({...obj, [n]: true}), {});
const NOT_TRANSLATION_SPECIFIERS = toObjectKeys(config.ignoreLocalImports);
let identifiers = {};
return {
ImportDeclaration(node) {
if (!node.source.value.startsWith(config.translateModulePrefix)) return;
for (let s of node.specifiers) {
const identifier = s.local.name;
if (NOT_TRANSLATION_SPECIFIERS.hasOwnProperty(identifier)) continue;
identifiers[identifier] = true;
}
},
Identifier(node) {
if (!identifiers.hasOwnProperty(node.name)) return;
const validParent = parentCallExpressionWithIdentifier(
node.parent,
config.translateFunctionIdentifier,
);
if (node.parent.type !== 'MemberExpression' || validParent) {
return;
}
const name = translationTextFullName(node.parent);
context.report({
node,
message:
'Expected {{ identifier }} to be argument of translate function {{ translateFunction }}',
data: {
identifier: name,
translateFunction: config.translateFunctionIdentifier,
},
});
},
};
},
};
function parentCallExpressionWithIdentifier(node, identifier) {
if (!node) return false;
if (
node.type === 'CallExpression' &&
node.callee &&
node.callee.name === identifier
) {
return node;
}
return parentCallExpressionWithIdentifier(node.parent, identifier);
}
function translationTextFullName(node) {
const base = node.object.name;
const prop = node.property.name;
return `${base}.${prop}.${onlyProperties(node.parent)}`.slice(0, -1);
}
function onlyProperties(node) {
if (node.type !== 'MemberExpression' || !node.property) return '';
if (!node.property || !node.property.name) return '';
return `${node.property.name}.${onlyProperties(node.parent)}`;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment