]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Rule to check spacing between template tags and their literals | |
3 | * @author Jonathan Wilsson | |
4 | */ | |
5 | ||
6 | "use strict"; | |
7 | ||
8 | //------------------------------------------------------------------------------ | |
9 | // Rule Definition | |
10 | //------------------------------------------------------------------------------ | |
11 | ||
34eeec05 | 12 | /** @type {import('../shared/types').Rule} */ |
eb39fafa DC |
13 | module.exports = { |
14 | meta: { | |
15 | type: "layout", | |
16 | ||
17 | docs: { | |
8f9d1d4d | 18 | description: "Require or disallow spacing between template tags and their literals", |
eb39fafa DC |
19 | recommended: false, |
20 | url: "https://eslint.org/docs/rules/template-tag-spacing" | |
21 | }, | |
22 | ||
23 | fixable: "whitespace", | |
24 | ||
25 | schema: [ | |
26 | { enum: ["always", "never"] } | |
27 | ], | |
28 | messages: { | |
29 | unexpected: "Unexpected space between template tag and template literal.", | |
30 | missing: "Missing space between template tag and template literal." | |
31 | } | |
32 | }, | |
33 | ||
34 | create(context) { | |
35 | const never = context.options[0] !== "always"; | |
36 | const sourceCode = context.getSourceCode(); | |
37 | ||
38 | /** | |
39 | * Check if a space is present between a template tag and its literal | |
40 | * @param {ASTNode} node node to evaluate | |
41 | * @returns {void} | |
42 | * @private | |
43 | */ | |
44 | function checkSpacing(node) { | |
45 | const tagToken = sourceCode.getTokenBefore(node.quasi); | |
46 | const literalToken = sourceCode.getFirstToken(node.quasi); | |
47 | const hasWhitespace = sourceCode.isSpaceBetweenTokens(tagToken, literalToken); | |
48 | ||
49 | if (never && hasWhitespace) { | |
50 | context.report({ | |
51 | node, | |
d3726936 TL |
52 | loc: { |
53 | start: tagToken.loc.end, | |
54 | end: literalToken.loc.start | |
55 | }, | |
eb39fafa DC |
56 | messageId: "unexpected", |
57 | fix(fixer) { | |
58 | const comments = sourceCode.getCommentsBefore(node.quasi); | |
59 | ||
60 | // Don't fix anything if there's a single line comment after the template tag | |
61 | if (comments.some(comment => comment.type === "Line")) { | |
62 | return null; | |
63 | } | |
64 | ||
65 | return fixer.replaceTextRange( | |
66 | [tagToken.range[1], literalToken.range[0]], | |
67 | comments.reduce((text, comment) => text + sourceCode.getText(comment), "") | |
68 | ); | |
69 | } | |
70 | }); | |
71 | } else if (!never && !hasWhitespace) { | |
72 | context.report({ | |
73 | node, | |
d3726936 TL |
74 | loc: { |
75 | start: node.loc.start, | |
76 | end: literalToken.loc.start | |
77 | }, | |
eb39fafa DC |
78 | messageId: "missing", |
79 | fix(fixer) { | |
80 | return fixer.insertTextAfter(tagToken, " "); | |
81 | } | |
82 | }); | |
83 | } | |
84 | } | |
85 | ||
86 | return { | |
87 | TaggedTemplateExpression: checkSpacing | |
88 | }; | |
89 | } | |
90 | }; |