From 43d73b01b1023509e48c12142367234965fe0ba3 Mon Sep 17 00:00:00 2001 From: Bertie690 <136088738+Bertie690@users.noreply.github.com> Date: Tue, 29 Apr 2025 19:21:28 -0400 Subject: [PATCH] [Code] Added and enforced `no-fallthrough` + added eslint type checking (#5705) * Added and enforced `no-fallthrough` * Fixed errors * Fix package.json * Moved vule to biom * Fixed stuff * Added workspace files to .gitignore for anyone who wants to do this stuff * reverted accidental gitignore changes * Update biome.jsonc Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> * Update biome.jsonc Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> * Update pokemon-species.ts * Update biome.jsonc to apply reviews * Fixed package.json * Fix typo --------- Co-authored-by: Sirz Benjie <142067137+SirzBenjie@users.noreply.github.com> Co-authored-by: NightKev <34855794+DayKev@users.noreply.github.com> --- biome.jsonc | 20 +++++++++++++------- eslint.config.js | 14 +++++++------- public/locales | 2 +- src/data/moves/move.ts | 8 ++++---- src/data/pokemon-species.ts | 1 + src/data/weather.ts | 1 + src/system/settings/settings.ts | 1 + src/ui-inputs.ts | 4 +++- tsconfig.json | 2 +- 9 files changed, 32 insertions(+), 21 deletions(-) diff --git a/biome.jsonc b/biome.jsonc index 9d0e6a9b5ff..a433470cd90 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -38,6 +38,9 @@ "src/data/balance/tms.ts" ] }, + + // While it'd be nice to enable consistent sorting, enabling this causes issues due to circular import resolution order + // TODO: Remove if we ever get down to 0 circular imports "organizeImports": { "enabled": false }, "linter": { "ignore": [ @@ -55,13 +58,13 @@ }, "style": { "noVar": "error", - "useEnumInitializers": "off", + "useEnumInitializers": "off", // large enums like Moves/Species would make this cumbersome "useBlockStatements": "error", "useConst": "error", "useImportType": "error", - "noNonNullAssertion": "off", // TODO: Turn this on ASAP and fix all non-null assertions + "noNonNullAssertion": "off", // TODO: Turn this on ASAP and fix all non-null assertions in non-test files "noParameterAssign": "off", - "useExponentiationOperator": "off", + "useExponentiationOperator": "off", // Too typo-prone and easy to mixup with standard multiplication (* vs **) "useDefaultParameterLast": "off", // TODO: Fix spots in the codebase where this flag would be triggered, and then enable "useSingleVarDeclarator": "off", "useNodejsImportProtocol": "off", @@ -70,17 +73,20 @@ }, "suspicious": { "noDoubleEquals": "error", + // While this would be a nice rule to enable, the current structure of the codebase makes this infeasible + // due to being used for move/ability `args` params and save data-related code. + // This can likely be enabled for all non-utils files once these are eventually reworked, but until then we leave it off. "noExplicitAny": "off", "noAssignInExpressions": "off", "noPrototypeBuiltins": "off", - "noFallthroughSwitchClause": "off", - "noImplicitAnyLet": "info", // TODO: Refactor and make this an error - "noRedeclare": "off", // TODO: Refactor and make this an error + "noFallthroughSwitchClause": "error", // Prevents accidental automatic fallthroughs in switch cases (use disable comment if needed) + "noImplicitAnyLet": "warn", // TODO: Refactor and make this an error + "noRedeclare": "info", // TODO: Refactor and make this an error "noGlobalIsNan": "off", "noAsyncPromiseExecutor": "warn" // TODO: Refactor and make this an error }, "complexity": { - "noExcessiveCognitiveComplexity": "warn", + "noExcessiveCognitiveComplexity": "warn", // TODO: Refactor and make this an error "useLiteralKeys": "off", "noForEach": "off", // Foreach vs for of is not that simple. "noUselessSwitchCase": "off", // Explicit > Implicit diff --git a/eslint.config.js b/eslint.config.js index a97e3902411..aebcab7feae 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,9 +1,10 @@ -import tseslint from "@typescript-eslint/eslint-plugin"; +/** @ts-check */ +import tseslint from "typescript-eslint"; import stylisticTs from "@stylistic/eslint-plugin-ts"; import parser from "@typescript-eslint/parser"; import importX from "eslint-plugin-import-x"; -export default [ +export default tseslint.config( { name: "eslint-config", files: ["src/**/*.{ts,tsx,js,jsx}", "test/**/*.{ts,tsx,js,jsx}"], @@ -14,12 +15,11 @@ export default [ plugins: { "import-x": importX, "@stylistic/ts": stylisticTs, - "@typescript-eslint": tseslint, + "@typescript-eslint": tseslint.plugin, }, rules: { - "prefer-const": "error", // Enforces the use of `const` for variables that are never reassigned "no-undef": "off", // Disables the rule that disallows the use of undeclared variables (TypeScript handles this) - "no-extra-semi": ["error"], // Disallows unnecessary semicolons for TypeScript-specific syntax + "no-extra-semi": "error", // Disallows unnecessary semicolons for TypeScript-specific syntax "import-x/extensions": ["error", "never", { json: "always" }], // Enforces no extension for imports unless json }, }, @@ -33,11 +33,11 @@ export default [ }, }, plugins: { - "@typescript-eslint": tseslint, + "@typescript-eslint": tseslint.plugin, }, rules: { "@typescript-eslint/no-floating-promises": "error", // Require Promise-like statements to be handled appropriately. - https://typescript-eslint.io/rules/no-floating-promises/ "@typescript-eslint/no-misused-promises": "error", // Disallow Promises in places not designed to handle them. - https://typescript-eslint.io/rules/no-misused-promises/ }, }, -]; +); diff --git a/public/locales b/public/locales index 18c1963ef30..e98f0eb9c20 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 18c1963ef309612a5a7fef76f9879709a7202189 +Subproject commit e98f0eb9c2022bc78b53f0444424c636498e725a diff --git a/src/data/moves/move.ts b/src/data/moves/move.ts index 6f854a3bbd8..9b8703d6e85 100644 --- a/src/data/moves/move.ts +++ b/src/data/moves/move.ts @@ -652,7 +652,7 @@ export default class Move implements Localizable { break; case MoveFlags.IGNORE_ABILITIES: if (user.hasAbilityWithAttr(MoveAbilityBypassAbAttr)) { - const abilityEffectsIgnored = new BooleanHolder(false); + const abilityEffectsIgnored = new BooleanHolder(false); applyAbAttrs(MoveAbilityBypassAbAttr, user, abilityEffectsIgnored, false, this); if (abilityEffectsIgnored.value) { return true; @@ -3160,7 +3160,7 @@ export class StatStageChangeAttr extends MoveEffectAttr { private get showMessage () { return this.options?.showMessage ?? true; } - + /** * Attempts to change stats of the user or target (depending on value of selfTarget) if conditions are met * @param user {@linkcode Pokemon} the user of the move @@ -6326,11 +6326,11 @@ export class ForceSwitchOutAttr extends MoveEffectAttr { if (!allyPokemon?.isActive(true) && switchOutTarget.hp) { globalScene.pushPhase(new BattleEndPhase(false)); - + if (globalScene.gameMode.hasRandomBiomes || globalScene.isNewBiome()) { globalScene.pushPhase(new SelectBiomePhase()); } - + globalScene.pushPhase(new NewBattlePhase()); } } diff --git a/src/data/pokemon-species.ts b/src/data/pokemon-species.ts index 2fff2b562c0..5a9a6ee9b3d 100644 --- a/src/data/pokemon-species.ts +++ b/src/data/pokemon-species.ts @@ -488,6 +488,7 @@ export abstract class PokemonSpeciesForm { if (formSpriteKey.startsWith("behemoth")) { formSpriteKey = "crowned"; } + // biome-ignore lint/suspicious/no-fallthrough: Falls through default: ret += `-${formSpriteKey}`; break; diff --git a/src/data/weather.ts b/src/data/weather.ts index 81559304661..be9107798df 100644 --- a/src/data/weather.ts +++ b/src/data/weather.ts @@ -369,6 +369,7 @@ export function getRandomWeatherType(arena: Arena): WeatherType { if (hasSun) { weatherPool.push({ weatherType: WeatherType.SUNNY, weight: 2 }); } + break; case Biome.VOLCANO: weatherPool = [ { diff --git a/src/system/settings/settings.ts b/src/system/settings/settings.ts index 31faf2b6283..8bbba267bd6 100644 --- a/src/system/settings/settings.ts +++ b/src/system/settings/settings.ts @@ -804,6 +804,7 @@ export function setSetting(setting: string, value: number): boolean { break; case SettingKeys.Candy_Upgrade_Display: globalScene.candyUpgradeDisplay = value; + break; case SettingKeys.Money_Format: switch (Setting[index].options[value].value) { case "Normal": diff --git a/src/ui-inputs.ts b/src/ui-inputs.ts index bf4f51e5af7..0c13cdb9512 100644 --- a/src/ui-inputs.ts +++ b/src/ui-inputs.ts @@ -176,11 +176,13 @@ export class UiInputs { return; } switch (globalScene.ui?.getMode()) { - case UiMode.MESSAGE: + case UiMode.MESSAGE: { const messageHandler = globalScene.ui.getHandler(); if (!messageHandler.pendingPrompt || messageHandler.isTextAnimationInProgress()) { return; } + // biome-ignore lint/suspicious/noFallthroughSwitchClause: falls through to show menu overlay + } case UiMode.TITLE: case UiMode.COMMAND: case UiMode.MODIFIER_SELECT: diff --git a/tsconfig.json b/tsconfig.json index 30e208745b9..6af3e9ce650 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,7 @@ "esModuleInterop": true, "strictNullChecks": true, "sourceMap": false, - "strict": false, + "strict": false, // TODO: Enable this eventually "rootDir": ".", "baseUrl": "./src", "paths": {