Skip to content

Commit 1cb6f2e

Browse files
committed
Support function and variable declarations after the final return in components-return-once, valid because of hoisting. Closes #163.
1 parent 740f2c8 commit 1cb6f2e

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

packages/eslint-plugin-solid/src/rules/components-return-once.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,9 @@ export default createRule({
6161
const onFunctionEnter = (node: FunctionNode) => {
6262
let lastReturn: T.ReturnStatement | undefined;
6363
if (node.body.type === "BlockStatement") {
64-
const { length } = node.body.body;
65-
const last = length && node.body.body[length - 1];
64+
// find last statement, ignoring function/class/variable declarations (hoisting)
65+
const last = node.body.body.findLast((node) => !node.type.endsWith("Declaration"));
66+
// if it's a return, store it
6667
if (last && last.type === "ReturnStatement") {
6768
lastReturn = last;
6869
}
@@ -153,7 +154,7 @@ export default createRule({
153154
return fixer.replaceText(argument, `<>${putIntoJSX(argument)}</>`);
154155
},
155156
});
156-
} else if (argument?.type === "LogicalExpression")
157+
} else if (argument?.type === "LogicalExpression") {
157158
if (argument.operator === "&&") {
158159
const sourceCode = getSourceCode(context);
159160
// we have a `return condition && expression`--put that in a <Show />
@@ -175,6 +176,7 @@ export default createRule({
175176
messageId: "noConditionalReturn",
176177
});
177178
}
179+
}
178180
}
179181

180182
// Pop on exit

packages/eslint-plugin-solid/test/rules/components-return-once.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ export const cases = run("components-return-once", rule, {
4949
};
5050
return <></>;
5151
}`,
52+
`function Component() {
53+
return <>{hoisted()}</>;
54+
function hoisted() {
55+
return 'hoisted';
56+
}
57+
}`,
58+
`function Component() {
59+
return <></>;
60+
const hoisted = 'hoisted';
61+
}`,
62+
`function Component() {
63+
return <></>;
64+
class Hoisted {}
65+
}`,
5266
],
5367
invalid: [
5468
// Early returns
@@ -70,6 +84,16 @@ export const cases = run("components-return-once", rule, {
7084
}`,
7185
errors: [{ messageId: "noEarlyReturn" }],
7286
},
87+
{
88+
code: `const Component = () => {
89+
if (condition) {
90+
return <div />;
91+
}
92+
return <span />;
93+
function hoisted() {}
94+
}`,
95+
errors: [{ messageId: "noEarlyReturn" }],
96+
},
7397
// Balanced ternaries
7498
{
7599
code: `function Component() {

0 commit comments

Comments
 (0)