add rule noNestedTernary and tests
MODIFY
packages/@romefrontend/compiler/lint/rules/index.ts
packages/@romefrontend/compiler/lint/rules/index.ts
@@ -36,6 +36,7 @@ import noFunctionAssign from "./js/noFunctionAssign";
import noImportAssign from "./js/noImportAssign";
import noLabelVar from "./js/noLabelVar";
import noMultipleSpacesInRegularExpressionLiterals from "./js/noMultipleSpacesInRegularExpressionLiterals";
+import noNestedTernary from "./js/noNestedTernary";
import noPosixInRegularExpression from "./js/noPosixInRegularExpression";
import noReferenceToNonExistingGroup from "./js/noReferenceToNonExistingGroup";
import noSetterReturn from "./js/noSetterReturn";
@@ -142,6 +143,7 @@ export const lintTransforms = [
noImportAssign,
noLabelVar,
noMultipleSpacesInRegularExpressionLiterals,
+ noNestedTernary,
noPosixInRegularExpression,
noReferenceToNonExistingGroup,
noSetterReturn,

ADD
packages/@romefrontend/compiler/lint/rules/js/noNestedTernary.test.ts
+import {test} from "rome";
+import {testLint} from "../../utils/testing";
+
+test(
+ "js no nested ternary",
+ async (t) => {
+ await testLint(
+ t,
+ {
+ invalid: [
+ "let thing = foo ? bar : baz === qux ? quxx : foobar;",
+ "let thing = foo ? bar ? boo : foo : baz ? boo : foo;",
+ "foo ? baz === qux ? quxx() : foobar() : bar();",
+ ],
+ valid: [
+ "let thing = foo ? bar : foobar;",
+ "let thing = foo ? bar || boo : foo || bar;",
+ "let thing = foo ? bar && boo : foo && bar;",
+ "let thing = foo || baz ? bar || boo : foo || bar;",
+ "let thing = foo && baz ? bar || boo : foo && bar;",
+ "let thing = foo || baz ? bar || boo : foo && bar;",
+ `
+ if (foo) {
+ thing = bar;
+ } else if (baz === qux) {
+ thing = quxx;
+ } else {
+ thing = foobar;
+ }
+ `,
+ ],
+ },
+ {category: "lint/js/noNestedTernary"},
+ );
+ },
+);

ADD
packages/@romefrontend/compiler/lint/rules/js/noNestedTernary.ts
+import {Path, TransformExitResult} from "@romefrontend/compiler";
+import {descriptions} from "@romefrontend/diagnostics";
+
+export default {
+ name: "jsNoNestedTernary",
+ enter(path: Path): TransformExitResult {
+ const {node} = path;
+
+ if (node.type === "JSConditionalExpression") {
+ if (node.alternate.type === "JSConditionalExpression") {
+ path.context.addNodeDiagnostic(
+ node.alternate,
+ descriptions.LINT.JS_NO_NESTED_TERNARY,
+ );
+ }
+ if (node.consequent.type === "JSConditionalExpression") {
+ path.context.addNodeDiagnostic(
+ node.consequent,
+ descriptions.LINT.JS_NO_NESTED_TERNARY,
+ );
+ }
+ }
+
+ return node;
+ },
+};

MODIFY
packages/@romefrontend/diagnostics/categories.ts
packages/@romefrontend/diagnostics/categories.ts
@@ -127,6 +127,7 @@ type LintDiagnosticCategory =
| "lint/js/noImportAssign"
| "lint/js/noLabelVar"
| "lint/js/noMultipleSpacesInRegularExpressionLiterals"
+ | "lint/js/noNestedTernary"
| "lint/js/noPosixInRegularExpression"
| "lint/js/noReferenceToNonExistingGroup"
| "lint/js/noSetterReturn"

MODIFY
packages/@romefrontend/diagnostics/descriptions/jsParser.ts
packages/@romefrontend/diagnostics/descriptions/jsParser.ts
@@ -234,26 +234,37 @@ export const jsParser = createDiagnosticsCategory({
},
],
},
- INVALID_PARENTEHSIZED_LVAL: (patternType: undefined | "object" | "array") => ({
- message: "Invalid parenthesized binding",
- advice: patternType === "object"
- ? [
+ INVALID_PARENTEHSIZED_LVAL: (patternType: undefined | "object" | "array") => {
+ const message = "Invalid parenthesized binding";
+ if (patternType === "object") {
+ return {
+ message,
+ advice: [
{
type: "log",
category: "info",
text: "Did you use `({a}) = 0` instead of `({a} = 0)`?",
},
- ]
- : patternType === "array"
- ? [
+ ],
+ };
+ } else if (patternType === "array") {
+ return {
+ message,
+ advice: [
{
type: "log",
category: "info",
text: "Did you use `([a]) = 0` instead of `([a] = 0)`?",
},
- ]
- : [],
- }),
+ ],
+ };
+ } else {
+ return {
+ message,
+ advice: [],
+ };
+ }
+ },
EXPECTED_COMMA_SEPARATOR: (context: string) => ({
message: `Expected a comma to separate items in ${context}`,
}),

MODIFY
packages/@romefrontend/diagnostics/descriptions/lint.ts
packages/@romefrontend/diagnostics/descriptions/lint.ts
@@ -16,6 +16,10 @@ import {buildSuggestionAdvice} from "../helpers";
import {createDiagnosticsCategory, orJoin} from "./index";
export const lint = createDiagnosticsCategory({
+ JS_NO_NESTED_TERNARY: {
+ category: "lint/js/noNestedTernary",
+ message: "Nesting ternary expressions can make code more difficult to understand.",
+ },
JSX_FILE_EXTENSION: (ext: string, basename: string) => ({
category: "lint/jsx/fileExtension",
message: `Files with the <emphasis>${ext}</emphasis> extension cannot contain JSX elements.`,

MODIFY
packages/@romefrontend/formatter/builders/comments.ts
packages/@romefrontend/formatter/builders/comments.ts
@@ -54,11 +54,13 @@ export function printComment(
function printCommentSeparator(left: AnyNode, right: AnyNode): Token {
const linesBetween = getLinesBetween(left, right);
- return linesBetween === 0
- ? space
- : linesBetween === 1
- ? hardline
- : concat([hardline, hardline]);
+ if (linesBetween === 0) {
+ return space;
+ }
+ if (linesBetween === 1) {
+ return hardline;
+ }
+ return concat([hardline, hardline]);
}
export function printLeadingComment(

MODIFY
packages/@romefrontend/js-parser/parser/lval.ts
packages/@romefrontend/js-parser/parser/lval.ts
@@ -1000,13 +1000,16 @@ export function checkLVal(
parser.isParenthesized(expr) &&
!ALLOWED_PARENTHESIZED_LVAL_TYPES.includes(expr.type)
) {
+ let patternType: "object" | "array" | undefined;
+ if (expr.type === "JSBindingObjectPattern") {
+ patternType = "object";
+ }
+ if (expr.type === "JSBindingArrayPattern") {
+ patternType = "array";
+ }
parser.unexpectedDiagnostic({
description: descriptions.JS_PARSER.INVALID_PARENTEHSIZED_LVAL(
- expr.type === "JSBindingObjectPattern"
- ? "object"
- : expr.type === "JSBindingArrayPattern"
- ? "array"
- : undefined,
+ patternType,
),
loc: expr.loc,
});

MODIFY
website/src/docs/lint/rules/index.md
website/src/docs/lint/rules/index.md
@@ -46,6 +46,7 @@ showHero: false
| no-import-assign | |
| no-label-var | |
| no-multiple-spaces-in-regular-expression-literals | |
+| [no-nested-ternary](/docs/lint/rules/js/no-nested-ternary) | This rule bans use of nested ternaries |
| no-posix-in-regular-expression | |
| no-reference-to-non-existing-group | |
| no-setter-return | |

ADD
website/src/docs/lint/rules/js/no-nested-ternary.md
+---
+title: Rome
+layout: layouts/base.njk
+showHero: false
+description: This rule bans use of nested ternaries
+---
+
+# noNestedTernary
+
+not documented yet

add rule noNestedTernary and tests (#725)