Skip to content

Commit

Permalink
feat(eslint-plugin-formatjs): support template literal without var, fix
Browse files Browse the repository at this point in the history
  • Loading branch information
longlho committed Jan 27, 2021
1 parent a79e69b commit a048e25
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 29 deletions.
Expand Up @@ -22,8 +22,9 @@ function checkNode(
if (type === 'literal' && messageNode) {
context.report({
node: messageNode as Node,
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
});
} else if (!messageNode) {
context.report({
Expand Down
Expand Up @@ -16,6 +16,12 @@ defineMessage({
`intl.formatMessage({
defaultMessage: 'this is default message' + 'vvv',
description: 'asd'
})`,
`intl.formatMessage({
defaultMessage: \`a template
literal
\`,
description: 'asd'
})`,
`import {FormattedMessage} from 'react-intl'
const a = <FormattedMessage defaultMessage={'asf' + 'bar'}/>`,
Expand Down Expand Up @@ -58,8 +64,9 @@ const a = <FormattedMessage defaultMessage={'asf' + 'bar'}/>`,
})`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
Expand All @@ -72,8 +79,9 @@ const a = <FormattedMessage defaultMessage={'asf' + 'bar'}/>`,
})`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
Expand All @@ -86,8 +94,9 @@ const a = <FormattedMessage defaultMessage={'asf' + 'bar'}/>`,
})`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
Expand Down Expand Up @@ -143,8 +152,9 @@ const a = <FormattedMessage defaultMessage={'asf' + 'bar'}/>`,
const a = <FormattedMessage defaultMessage={defaultMessage} description="this is description"/>`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
Expand All @@ -155,32 +165,35 @@ const a = <FormattedMessage defaultMessage={'asf' + 'bar'}/>`,
const a = <FormattedMessage defaultMessage={defaultMessage}/>`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
},
{
code: `
import {FormattedMessage} from 'react-intl'
const a = <FormattedMessage defaultMessage={\`asf\`} description="this is description"></FormattedMessage>`,
const a = <FormattedMessage defaultMessage={\`asf \${foo}\`} description="this is description"></FormattedMessage>`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
},
{
code: `
import {FormattedMessage} from 'react-intl'
const a = <FormattedMessage defaultMessage={\`asf\`}/>`,
const a = <FormattedMessage defaultMessage={\`asf \${aas}\`}/>`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
Expand Down Expand Up @@ -226,8 +239,9 @@ vueRuleTester.run('vue/enforce-default-message', enforceDefaultMessage, {
})}}</p></template>`,
errors: [
{
message:
'`defaultMessage` must be a string literal (not function call or variable)',
message: `"defaultMessage" must be:
- a string literal or
- template literal without variable`,
},
],
options: ['literal'],
Expand Down
26 changes: 17 additions & 9 deletions packages/eslint-plugin-formatjs/util.ts
Expand Up @@ -20,6 +20,12 @@ function isStringLiteral(node: TSESTree.Node): node is TSESTree.StringLiteral {
return node.type === 'Literal' && typeof node.value === 'string';
}

function isTemplateLiteralWithoutVar(
node: TSESTree.Node
): node is TSESTree.TemplateLiteral {
return node.type === 'TemplateLiteral' && node.quasis.length === 1;
}

function findReferenceImport(
id: TSESTree.Identifier,
importedVars: Scope.Variable[]
Expand Down Expand Up @@ -116,6 +122,8 @@ function extractMessageDescriptor(
let value: string | undefined = undefined;
if (isStringLiteral(valueNode)) {
value = valueNode.value;
} else if (isTemplateLiteralWithoutVar(valueNode)) {
value = valueNode.quasis[0].value.cooked;
} else if (valueNode.type === 'BinaryExpression') {
const [result, isStatic] = staticallyEvaluateStringConcat(valueNode);
if (isStatic) {
Expand Down Expand Up @@ -170,15 +178,15 @@ function extractMessageDescriptorFromJSXElement(
if (valueNode) {
if (isStringLiteral(valueNode)) {
value = valueNode.value;
} else if (
valueNode?.type === 'JSXExpressionContainer' &&
valueNode.expression.type === 'BinaryExpression'
) {
const [result, isStatic] = staticallyEvaluateStringConcat(
valueNode.expression
);
if (isStatic) {
value = result;
} else if (valueNode?.type === 'JSXExpressionContainer') {
const {expression} = valueNode;
if (expression.type === 'BinaryExpression') {
const [result, isStatic] = staticallyEvaluateStringConcat(expression);
if (isStatic) {
value = result;
}
} else if (isTemplateLiteralWithoutVar(expression)) {
value = expression.quasis[0].value.cooked;
}
}
}
Expand Down

0 comments on commit a048e25

Please sign in to comment.