diff --git a/README.md b/README.md
index 9c5fba7..54f2696 100644
--- a/README.md
+++ b/README.md
@@ -579,6 +579,56 @@ $bar = (integer) $count;
+### yCodeTech.Types.DisallowVoidType
+
+Explicit `void` return type declarations are disallowed on functions, methods, and closures. The absence of a return type already implies void.
+
+
+
+ | Rules |
+ Fixable? |
+
+
+ Explicit : void return type declarations must be removed. |
+ ✔️ |
+
+
+
+#### Violation Codes:
+
+`yCodeTech.Types.DisallowVoidType.Found`
+
+#### Examples:
+
+
+
+ | ✔️ Valid: No return type (implicitly void) |
+ ❌ Invalid: Explicit void return type |
+
+
+|
+
+```php
+function doSomething()
+{
+ echo "Hello";
+}
+```
+
+ |
+
+
+```php
+function doSomething(): void
+{
+ echo "Hello";
+}
+```
+
+ |
+
+
+
## Testing
To test the standard against the provided comprehensive test file, please see [the specific instructions](./test_utils/README.md).
diff --git a/test_utils/TestFile.php b/test_utils/TestFile.php
index 44326a1..ad842b9 100644
--- a/test_utils/TestFile.php
+++ b/test_utils/TestFile.php
@@ -270,11 +270,14 @@ public function testMissingGeneratorReturn()
***********************/
/**
- * Function that returns void with an explicit `void` typing
- * (should NOT be flagged for missing `@return` tag).
+ * Function that returns void with an explicit `void` typing
+ * (should be flagged for explicit void type, but NOT for missing `@return` tag).
+ *
+ * The following should be fixed:
+ * - The explicit `: void` return type should be removed.
*
* The following should NOT be fixed:
- * - A `@return` tag should not be added for an explicit `void` return.
+ * - A `@return` tag should not be added.
*
* @param string $message Message to display
*/
@@ -360,6 +363,7 @@ function testVoidFunctionWithAnonymousFunction()
*
* The following should be fixed:
* - The `@return` tag should be removed.
+ * - The explicit `: void` return type should be removed.
*
* @return void
*/
diff --git a/test_utils/TestFile_WithErrors_DoNotFix.php b/test_utils/TestFile_WithErrors_DoNotFix.php
index 44326a1..ad842b9 100644
--- a/test_utils/TestFile_WithErrors_DoNotFix.php
+++ b/test_utils/TestFile_WithErrors_DoNotFix.php
@@ -270,11 +270,14 @@ public function testMissingGeneratorReturn()
***********************/
/**
- * Function that returns void with an explicit `void` typing
- * (should NOT be flagged for missing `@return` tag).
+ * Function that returns void with an explicit `void` typing
+ * (should be flagged for explicit void type, but NOT for missing `@return` tag).
+ *
+ * The following should be fixed:
+ * - The explicit `: void` return type should be removed.
*
* The following should NOT be fixed:
- * - A `@return` tag should not be added for an explicit `void` return.
+ * - A `@return` tag should not be added.
*
* @param string $message Message to display
*/
@@ -360,6 +363,7 @@ function testVoidFunctionWithAnonymousFunction()
*
* The following should be fixed:
* - The `@return` tag should be removed.
+ * - The explicit `: void` return type should be removed.
*
* @return void
*/
diff --git a/yCodeTech/Docs/Types/DisallowVoidTypeStandard.xml b/yCodeTech/Docs/Types/DisallowVoidTypeStandard.xml
new file mode 100644
index 0000000..2185019
--- /dev/null
+++ b/yCodeTech/Docs/Types/DisallowVoidTypeStandard.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+ : void
+{
+ echo "Hello";
+}
+ ]]>
+
+
+
diff --git a/yCodeTech/Sniffs/Types/DisallowVoidTypeSniff.php b/yCodeTech/Sniffs/Types/DisallowVoidTypeSniff.php
new file mode 100644
index 0000000..ee1105f
--- /dev/null
+++ b/yCodeTech/Sniffs/Types/DisallowVoidTypeSniff.php
@@ -0,0 +1,144 @@
+
+ */
+ public function register()
+ {
+ return [T_FUNCTION, T_CLOSURE];
+ }
+
+ /**
+ * Processes this test, when one of its tokens is encountered.
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the current token in the
+ * stack passed in $tokens.
+ */
+ public function process(File $phpcsFile, $stackPtr)
+ {
+ $voidPtr = $this->getExplicitVoidTypePtr($phpcsFile, $stackPtr);
+ if ($voidPtr === false) {
+ return;
+ }
+
+ $error = 'Explicit void return type is not allowed and should be removed';
+ $fix = $phpcsFile->addFixableError($error, $voidPtr, 'Found');
+ if ($fix === true) {
+ $this->removeExplicitVoidType($phpcsFile, $stackPtr);
+ }
+ }
+
+ /**
+ * Get the position of the explicit `void` return type token, if present.
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function token.
+ *
+ * @return int|false The position of the void token, or false if not found.
+ */
+ private function getExplicitVoidTypePtr(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $openParen = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr);
+ if ($openParen === false) {
+ return false;
+ }
+
+ $closeParen = $tokens[$openParen]['parenthesis_closer'] ?? null;
+ if ($closeParen === null) {
+ return false;
+ }
+
+ $scopeOpener = $tokens[$stackPtr]['scope_opener'] ?? null;
+ $semicolonPtr = $phpcsFile->findNext(T_SEMICOLON, $closeParen + 1);
+ $searchEnd = $scopeOpener ?? ($semicolonPtr !== false ? $semicolonPtr + 1 : null);
+
+ $colonPtr = $phpcsFile->findNext(T_COLON, $closeParen + 1, $searchEnd);
+ if ($colonPtr === false) {
+ return false;
+ }
+
+ $returnTypePtr = $phpcsFile->findNext(T_WHITESPACE, $colonPtr + 1, null, true);
+ if ($returnTypePtr === false) {
+ return false;
+ }
+
+ if ($tokens[$returnTypePtr]['code'] === T_STRING && $tokens[$returnTypePtr]['content'] === 'void') {
+ return $returnTypePtr;
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove explicit `: void` return type from a function signature.
+ *
+ * Removes the colon, any whitespace between colon and void, and the `void`
+ * token itself, leaving the rest of the signature intact.
+ *
+ * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
+ * @param int $stackPtr The position of the function token.
+ */
+ private function removeExplicitVoidType(File $phpcsFile, $stackPtr)
+ {
+ $tokens = $phpcsFile->getTokens();
+
+ $openParen = $phpcsFile->findNext(T_OPEN_PARENTHESIS, $stackPtr);
+ if ($openParen === false) {
+ return;
+ }
+
+ $closeParen = $tokens[$openParen]['parenthesis_closer'] ?? null;
+ if ($closeParen === null) {
+ return;
+ }
+
+ $scopeOpener = $tokens[$stackPtr]['scope_opener'] ?? null;
+ $semicolonPtr = $phpcsFile->findNext(T_SEMICOLON, $closeParen + 1);
+ $searchEnd = $scopeOpener ?? ($semicolonPtr !== false ? $semicolonPtr + 1 : null);
+
+ $colonPtr = $phpcsFile->findNext(T_COLON, $closeParen + 1, $searchEnd);
+ if ($colonPtr === false) {
+ return;
+ }
+
+ $voidPtr = $phpcsFile->findNext(T_WHITESPACE, $colonPtr + 1, null, true);
+ if ($voidPtr === false || $tokens[$voidPtr]['content'] !== 'void') {
+ return;
+ }
+
+ $phpcsFile->fixer->beginChangeset();
+ for ($i = $colonPtr; $i <= $voidPtr; $i++) {
+ $phpcsFile->fixer->replaceToken($i, '');
+ }
+ $phpcsFile->fixer->endChangeset();
+ }
+}
diff --git a/yCodeTech/Tests/Types/DisallowVoidTypeUnitTest.inc b/yCodeTech/Tests/Types/DisallowVoidTypeUnitTest.inc
new file mode 100644
index 0000000..686154a
--- /dev/null
+++ b/yCodeTech/Tests/Types/DisallowVoidTypeUnitTest.inc
@@ -0,0 +1,40 @@
+
+ */
+ public function getErrorList()
+ {
+ return [
+ 14 => 1, // explicitVoidMethod(): void
+ 19 => 1, // explicitVoidWithParam(): void
+ 37 => 1, // explicitVoidFunction(): void
+ ];
+ }
+
+ /**
+ * Returns the lines where warnings should occur.
+ *
+ * The key of the array should represent the line number and the value
+ * should represent the number of warnings that should occur on that line.
+ *
+ * @return array
+ */
+ public function getWarningList()
+ {
+ return [];
+ }
+}