diff --git a/.changeset/few-ducks-mate.md b/.changeset/few-ducks-mate.md new file mode 100644 index 0000000..abd2dcd --- /dev/null +++ b/.changeset/few-ducks-mate.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-php': minor +--- + +Add `disallow-references` rule diff --git a/README.md b/README.md index 09f54f7..58b3eee 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,9 @@ export default defineConfig([ 💡 - Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions). -| Rule ID | Description | 🔧 | 💡 | -| ------------------------ | --------------------------------------------------- | --- | --- | -| `php/eqeqeq` | Require the use of `===` and `!==` | | | -| `php/no-array-keyword` | Disallow the use of the array keyword | 🔧 | | -| `php/require-visibility` | Require visibility for class methods and properties | | 💡 | +| Rule ID | Description | 🔧 | 💡 | +| ------------------------- | --------------------------------------------------- | --- | --- | +| `php/disallow-references` | Disallow the use of references | | 💡 | +| `php/eqeqeq` | Require the use of `===` and `!==` | | | +| `php/no-array-keyword` | Disallow the use of the array keyword | 🔧 | | +| `php/require-visibility` | Require visibility for class methods and properties | | 💡 | diff --git a/src/index.ts b/src/index.ts index ac570d9..0033488 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import { ESLint } from 'eslint'; import { PHPLanguage } from './language/php-language'; +import { disallowReferences } from './rules/disallow-references'; import { eqeqeq } from './rules/eqeqeq'; import { noArrayKeyword } from './rules/no-array-keyword'; import { requireVisibility } from './rules/require-visibility'; @@ -14,6 +15,7 @@ const plugin = { php: new PHPLanguage(), }, rules: { + 'disallow-references': disallowReferences, eqeqeq, 'no-array-keyword': noArrayKeyword, 'require-visibility': requireVisibility, diff --git a/src/rules/__tests__/disallow-references.test.ts b/src/rules/__tests__/disallow-references.test.ts new file mode 100644 index 0000000..e225889 --- /dev/null +++ b/src/rules/__tests__/disallow-references.test.ts @@ -0,0 +1,97 @@ +import { RuleTester, type Rule } from 'eslint'; +import php from '../../index'; +import { disallowReferences } from '../disallow-references'; + +const ruleTester = new RuleTester({ + plugins: { + php, + }, + language: 'php/php', +}); + +// TODO: Fix the types. +ruleTester.run( + 'disallow-references', + disallowReferences as unknown as Rule.RuleModule, + { + valid: [ + '({ + meta: { + type: 'suggestion', + fixable: 'code', + hasSuggestions: true, + docs: { + description: 'Disallow the use of references', + }, + messages: { + disallowReferences: 'Do not use references (&).', + removeAmp: 'Remove the reference operator (&).', + }, + schema: [], + }, + + create(context) { + return { + 'assignref > .right, parameter[byref="true"], function[byref="true"] > .name, variable[byref="true"]'( + node, + ) { + const ampKeyWord = context.sourceCode.findClosestKeyword( + node, + '&', + ); + + if (!ampKeyWord) { + return; + } + + context.report({ + node, + loc: { + start: ampKeyWord.start, + end: context.sourceCode.getLoc(node).end, + }, + messageId: 'disallowReferences', + suggest: [ + { + messageId: 'removeAmp', + fix(fixer) { + return fixer.removeRange([ + ampKeyWord.start.offset, + ampKeyWord.end.offset, + ]); + }, + }, + ], + }); + }, + }; + }, +});