Skip to content

Commit

Permalink
fix: fix base indent in template literals (#242)
Browse files Browse the repository at this point in the history
  • Loading branch information
yeonjuan authored Dec 3, 2024
1 parent 4990e2d commit d68884b
Show file tree
Hide file tree
Showing 2 changed files with 287 additions and 20 deletions.
101 changes: 96 additions & 5 deletions packages/eslint-plugin/lib/rules/indent.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@
* @typedef { import("../types").LineNode } LineNode
* @typedef { import("../types").BaseNode } BaseNode
* @typedef { import("../types").TagNode } TagNode
* @typedef { import("../types").RuleListener } RuleListener
* @typedef { import("eslint").AST.Token } Token
* @typedef { import("eslint").SourceCode } SourceCode
* @typedef { import("estree").TemplateLiteral } TemplateLiteral
* @typedef {Object} IndentType
* @property {"tab"} TAB
* @property {"space"} SPACE
* @typedef {Object} MessageId
* @property {"wrongIndent"} WRONG_INDENT
*/

const { parse } = require("@html-eslint/template-parser");
const { RULE_CATEGORY } = require("../constants");
const { splitToLineNodes } = require("./utils/node");
const {
shouldCheckTaggedTemplateExpression,
shouldCheckTemplateLiteral,
} = require("./utils/settings");
const { getSourceCode } = require("./utils/source-code");
const { createVisitors } = require("./utils/visitors");

/** @type {MessageId} */
const MESSAGE_ID = {
Expand Down Expand Up @@ -63,6 +71,8 @@ module.exports = {
},
create(context) {
const sourceCode = getSourceCode(context);

let baseIndentLevel = 0;
let indentLevel = -1;
let parentIgnoringChildCount = 0;

Expand Down Expand Up @@ -91,6 +101,9 @@ module.exports = {
function unindent() {
indentLevel--;
}
function getIndentLevel() {
return indentLevel + baseIndentLevel;
}

/**
* @param {string} str
Expand Down Expand Up @@ -128,7 +141,7 @@ module.exports = {
* @returns {string}
*/
function getExpectedIndent() {
return indentChar.repeat(indentLevel);
return indentChar.repeat(getIndentLevel());
}

/**
Expand Down Expand Up @@ -199,6 +212,7 @@ module.exports = {
}
const actualIndent = getActualIndent(node);
const expectedIndent = getExpectedIndent();

if (actualIndent.trim().length) {
return;
}
Expand All @@ -207,15 +221,66 @@ module.exports = {
context.report({
node: targetNode,
messageId: MESSAGE_ID.WRONG_INDENT,
data: getMessageData(actualIndent, indentLevel),
data: getMessageData(actualIndent, getIndentLevel()),
fix(fixer) {
return fixer.replaceText(targetNode, expectedIndent);
},
});
}
}

return createVisitors(context, {
/**
*
* @param {Token} token
*/
function getBaseIndentToken(token) {
/**
* @type {Token | null}
*/
let currentToken = token;
let tokenBefore = token;

while (
// @ts-ignore
(tokenBefore = sourceCode.getTokenBefore(currentToken, {
includeComments: true,
}))
) {
if (!tokenBefore) {
return currentToken;
}
if (tokenBefore.loc.start.line !== currentToken.loc.start.line) {
return currentToken;
}
currentToken = tokenBefore;
}
return tokenBefore;
}

/**
*
* @param {TemplateLiteral} node
* @returns {number}
*/
function getBaseIndentLevel(node) {
const firstToken = sourceCode.getFirstToken(node);
if (!firstToken) return 0;
const baseToken = getBaseIndentToken(firstToken);
if (!baseToken) {
return 0;
}
const spaceCount = baseToken.loc.start.column;

if (indentType === "space") {
return Math.floor(spaceCount / indentSize);
} else {
return spaceCount;
}
}
/**
* @type {RuleListener}
*/
const visitor = {
Tag(node) {
if (IGNORING_NODES.includes(node.name)) {
parentIgnoringChildCount++;
Expand Down Expand Up @@ -282,6 +347,32 @@ module.exports = {
CommentClose: checkIndent,
"Comment:exit": unindent,
"CommentContent:exit": unindent,
});
};

return {
...visitor,
TaggedTemplateExpression(node) {
if (shouldCheckTaggedTemplateExpression(node, context)) {
baseIndentLevel = getBaseIndentLevel(node.quasi) + 1;
parse(node.quasi, getSourceCode(context), visitor);
}
},
"TaggedTemplateExpression:exit"(node) {
if (shouldCheckTaggedTemplateExpression(node, context)) {
baseIndentLevel = 0;
}
},
TemplateLiteral(node) {
if (shouldCheckTemplateLiteral(node, context)) {
baseIndentLevel = getBaseIndentLevel(node) + 1;
parse(node, getSourceCode(context), visitor);
}
},
"TemplateLiteral:exit"(node) {
if (shouldCheckTemplateLiteral(node, context)) {
baseIndentLevel = 0;
}
},
};
},
};
Loading

0 comments on commit d68884b

Please sign in to comment.