Disallow shouty constants
MODIFY
packages/@romefrontend/compiler/lint/rules/index.ts
packages/@romefrontend/compiler/lint/rules/index.ts
@@ -52,6 +52,7 @@ import preferFunctionDeclarations from "./js/preferFunctionDeclarations";
import preferTemplate from "./js/preferTemplate";
import preferWhile from "./js/preferWhile";
import restrictedGlobals from "./js/restrictedGlobals";
+import shoutyConstants from "./js/shoutyConstants";
import singleVarDeclarator from "./js/singleVarDeclarator";
import sortImportExportSpecifiers from "./js/sortImportExportSpecifiers";
import sparseArray from "./js/sparseArray";
@@ -161,6 +162,7 @@ export const lintTransforms = [
preferTemplate,
preferWhile,
restrictedGlobals,
+ shoutyConstants,
singleVarDeclarator,
sortImportExportSpecifiers,
sparseArray,

ADD
packages/@romefrontend/compiler/lint/rules/js/shoutyConstants.test.rjson
+filename: "file.ts"
+invalid: [
+ "
+ const FOO = \"FOO\";
+ console.log(FOO);
+ "
+ "
+ const FOO = \"FOO\";
+ function f() {
+ return FOO;
+ }
+ "
+ "
+ const FOO = \"FOO\", BAR = \"bar\";
+ console.log(FOO);
+ "
+]
+valid: [
+ "
+ let FOO = \"FOO\";
+ console.log(FOO);
+ "
+ "
+ export const FOO = \"FOO\";
+ console.log(FOO);
+ "
+ "
+ function f(FOO = \"FOO\") {
+ return FOO;
+ }
+ "
+]

ADD
packages/@romefrontend/compiler/lint/rules/js/shoutyConstants.ts
+import {ConstBinding, Path, TransformExitResult} from "@romefrontend/compiler";
+import {descriptions} from "@romefrontend/diagnostics";
+
+export default {
+ name: "shoutyConstants",
+ enter(path: Path): TransformExitResult {
+ const {node, scope} = path;
+
+ if (node.type === "JSReferenceIdentifier") {
+ const binding = scope.getBinding(node.name);
+ if (
+ binding instanceof ConstBinding &&
+ binding.value !== undefined &&
+ binding.value.type === "JSStringLiteral" &&
+ binding.value.value === node.name &&
+ !binding.isExported &&
+ (binding.scope.kind === "block" || binding.scope.kind === "program")
+ ) {
+ return path.context.addFixableDiagnostic(
+ {
+ old: node,
+ fixed: binding.value,
+ },
+ descriptions.LINT.JS_SHOUTY_CONSTANTS(binding.node.loc),
+ );
+ }
+ }
+
+ return node;
+ },
+};

MODIFY
packages/@romefrontend/compiler/lint/rules/tests.ts
packages/@romefrontend/compiler/lint/rules/tests.ts
@@ -99,6 +99,8 @@ import preferWhile from "./js/preferWhile.test.rjson";
// @ts-ignore
import restrictedGlobals from "./js/restrictedGlobals.test.rjson";
// @ts-ignore
+import shoutyConstants from "./js/shoutyConstants.test.rjson";
+// @ts-ignore
import singleVarDeclarator from "./js/singleVarDeclarator.test.rjson";
// @ts-ignore
import sortImportExportSpecifiers from "./js/sortImportExportSpecifiers.test.rjson";
@@ -152,6 +154,7 @@ export const tests: Tests = {
"js/preferTemplate": preferTemplate,
"js/preferWhile": preferWhile,
"js/restrictedGlobals": restrictedGlobals,
+ "js/shoutyConstants": shoutyConstants,
"js/singleVarDeclarator": singleVarDeclarator,
"js/sortImportExportSpecifiers": sortImportExportSpecifiers,
"js/sparseArray": sparseArray,

MODIFY
packages/@romefrontend/diagnostics/categories.ts
packages/@romefrontend/diagnostics/categories.ts
@@ -146,6 +146,7 @@ type LintDiagnosticCategory =
| "lint/js/preferTemplate"
| "lint/js/preferWhile"
| "lint/js/restrictedGlobals"
+ | "lint/js/shoutyConstants"
| "lint/js/singleVarDeclarator"
| "lint/js/sortImportExportSpecifiers"
| "lint/js/sparseArray"

MODIFY
packages/@romefrontend/diagnostics/descriptions/lint.ts
packages/@romefrontend/diagnostics/descriptions/lint.ts
@@ -17,6 +17,26 @@ import {buildSuggestionAdvice} from "../helpers";
import {createDiagnosticsCategory, orJoin} from "./index";
export const lint = createDiagnosticsCategory({
+ JS_SHOUTY_CONSTANTS: (constantLocation: DiagnosticLocation = {}) => ({
+ category: "lint/js/shoutyConstants",
+ message: "Redundant constant reference",
+ advice: [
+ {
+ type: "log",
+ category: "info",
+ text: "You should avoid declaring constants with a string that's the same value as the variable name. It introduces a level of unnecessary indirection when it's only two additional characters to inline.",
+ },
+ {
+ type: "log",
+ category: "info",
+ text: "This constant is declared here",
+ },
+ {
+ type: "frame",
+ location: constantLocation,
+ },
+ ],
+ }),
JS_NO_UNUSED_TEMPLATE_LITERAL: {
category: "lint/js/noUnusedTemplateLiteral",
message: "Do not use template literals if interpolation and special-character handling are not needed.",

DELETE
packages/@romefrontend/js-ast-utils/isIdentifier.ts
-

MODIFY
scripts/lint/add.cjs
scripts/lint/add.cjs
@@ -69,12 +69,12 @@ export default {
write(
testLoc,
`filename: "filename.ts"
-invalid": [
+invalid: [
"
// insert invalid examples here
"
]
-valid": [
+valid: [
"
// insert valid examples here
"

MODIFY
website/src/docs/lint/rules/index.md
website/src/docs/lint/rules/index.md
@@ -61,6 +61,7 @@ eleventyNavigation: {
- [preferTemplate](/docs/lint/rules/js/preferTemplate): MISSING DOCUMENTATION
- [preferWhile](/docs/lint/rules/js/preferWhile): MISSING DOCUMENTATION
- [restrictedGlobals](/docs/lint/rules/js/restrictedGlobals): MISSING DOCUMENTATION
+- [shoutyConstants](/docs/lint/rules/js/shoutyConstants): MISSING DOCUMENTATION
- [singleVarDeclarator](/docs/lint/rules/js/singleVarDeclarator): MISSING DOCUMENTATION
- [sortImportExportSpecifiers](/docs/lint/rules/js/sortImportExportSpecifiers): MISSING DOCUMENTATION
- [sparseArray](/docs/lint/rules/js/sparseArray): MISSING DOCUMENTATION
@@ -115,6 +116,7 @@ eleventyNavigation: {
- [preferTemplate](/docs/lint/rules/js/preferTemplate): MISSING DOCUMENTATION
- [preferWhile](/docs/lint/rules/js/preferWhile): MISSING DOCUMENTATION
- [restrictedGlobals](/docs/lint/rules/js/restrictedGlobals): MISSING DOCUMENTATION
+- [shoutyConstants](/docs/lint/rules/js/shoutyConstants): MISSING DOCUMENTATION
- [singleVarDeclarator](/docs/lint/rules/js/singleVarDeclarator): MISSING DOCUMENTATION
- [sortImportExportSpecifiers](/docs/lint/rules/js/sortImportExportSpecifiers): MISSING DOCUMENTATION
- [sparseArray](/docs/lint/rules/js/sparseArray): MISSING DOCUMENTATION
@@ -200,6 +202,7 @@ eleventyNavigation: {
- [preferTemplate](/docs/lint/rules/js/preferTemplate): MISSING DOCUMENTATION
- [preferWhile](/docs/lint/rules/js/preferWhile): MISSING DOCUMENTATION
- [restrictedGlobals](/docs/lint/rules/js/restrictedGlobals): MISSING DOCUMENTATION
+- [shoutyConstants](/docs/lint/rules/js/shoutyConstants): MISSING DOCUMENTATION
- [singleVarDeclarator](/docs/lint/rules/js/singleVarDeclarator): MISSING DOCUMENTATION
- [sortImportExportSpecifiers](/docs/lint/rules/js/sortImportExportSpecifiers): MISSING DOCUMENTATION
- [sparseArray](/docs/lint/rules/js/sparseArray): MISSING DOCUMENTATION
@@ -308,6 +311,7 @@ eleventyNavigation: {
- [preferTemplate](/docs/lint/rules/js/preferTemplate): MISSING DOCUMENTATION
- [preferWhile](/docs/lint/rules/js/preferWhile): MISSING DOCUMENTATION
- [restrictedGlobals](/docs/lint/rules/js/restrictedGlobals): MISSING DOCUMENTATION
+- [shoutyConstants](/docs/lint/rules/js/shoutyConstants): MISSING DOCUMENTATION
- [singleVarDeclarator](/docs/lint/rules/js/singleVarDeclarator): MISSING DOCUMENTATION
- [sortImportExportSpecifiers](/docs/lint/rules/js/sortImportExportSpecifiers): MISSING DOCUMENTATION
- [sparseArray](/docs/lint/rules/js/sparseArray): MISSING DOCUMENTATION

ADD
website/src/docs/lint/rules/js/shoutyConstants.md
+---
+title: Lint Rule js/shoutyConstants
+layout: layouts/page.njk
+description: MISSING DOCUMENTATION
+eleventyNavigation: {
+ key: lint-rules/js/shoutyConstants,
+ parent: lint-rules,
+ title: js/shoutyConstants
+}
+---
+
+# js/shoutyConstants
+
+MISSING DOCUMENTATION
+
+<!-- EVERYTHING BELOW IS AUTOGENERATED. SEE SCRIPTS FOLDER FOR UPDATE SCRIPTS -->
+
+
+## Examples
+## Invalid
+```typescript
+const FOO = "FOO";
+console.log(FOO);
+```
+```typescript
+const FOO = "FOO";
+function f() {
+ return FOO;
+}
+```
+```typescript
+const FOO = "FOO", BAR = "bar";
+console.log(FOO);
+```
+## Valid
+```typescript
+let FOO = "FOO";
+console.log(FOO);
+```
+```typescript
+export const FOO = "FOO";
+console.log(FOO);
+```
+```typescript
+function f(FOO = "FOO") {
+ return FOO;
+}
+```

MODIFY
website/src/sitemap.md
website/src/sitemap.md
@@ -84,6 +84,7 @@ layout: layouts/page.njk
- [`/preferTemplate`](/docs/lint/rules/js/preferTemplate): js/preferTemplate
- [`/preferWhile`](/docs/lint/rules/js/preferWhile): js/preferWhile
- [`/restrictedGlobals`](/docs/lint/rules/js/restrictedGlobals): js/restrictedGlobals
+ - [`/shoutyConstants`](/docs/lint/rules/js/shoutyConstants): js/shoutyConstants
- [`/singleVarDeclarator`](/docs/lint/rules/js/singleVarDeclarator): js/singleVarDeclarator
- [`/sortImportExportSpecifiers`](/docs/lint/rules/js/sortImportExportSpecifiers): js/sortImportExportSpecifiers
- [`/sparseArray`](/docs/lint/rules/js/sparseArray): js/sparseArray

Disallow shouty constants (#806)

Co-authored-by: Yasser Elassal <yassere@gmail.com>