diff --git a/src/Linters/UnusedPipeVariableLinter.hack b/src/Linters/UnusedPipeVariableLinter.hack new file mode 100644 index 000000000..6f18b6f5b --- /dev/null +++ b/src/Linters/UnusedPipeVariableLinter.hack @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +namespace Facebook\HHAST; + +final class UnusedPipeVariableLinter extends ASTLinter { + const type TConfig = shape(); + const type TNode = BinaryExpression; + const type TContext = Script; + + <<__Override>> + public function getLintErrorForNode( + Script $_script, + BinaryExpression $expr, + ): ?ASTLintError { + $op = $expr->getOperator(); + if (!$op is BarGreaterThanToken) { + return null; + } + $rhs = $expr->getRightOperand(); + $pipe_var = $rhs->getFirstDescendantOfType(PipeVariableExpression::class); + + if ($pipe_var is null) { + return new ASTLintError( + $this, + 'Missing pipe variable in right-hand side of pipe operator', + $expr, + ); + } + + return null; + } +} diff --git a/tests/UnusedPipeVariableLinterTest.hack b/tests/UnusedPipeVariableLinterTest.hack new file mode 100644 index 000000000..cc9dd3872 --- /dev/null +++ b/tests/UnusedPipeVariableLinterTest.hack @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +namespace Facebook\HHAST; + +final class UnusedPipeVariableLinterTest extends TestCase { + use LinterTestTrait; + + <<__Override>> + protected function getLinter(string $file): UnusedPipeVariableLinter { + return UnusedPipeVariableLinter::fromPath($file); + } + + <<__Override>> + public function getCleanExamples(): vec<(string)> { + return vec[ + tuple( + ' Str\uppercase($$); }', + ), + ]; + } +} diff --git a/tests/examples/UnusedPipeVariableLinter/unused_pipe.php.expect b/tests/examples/UnusedPipeVariableLinter/unused_pipe.php.expect new file mode 100644 index 000000000..ebc5b85fa --- /dev/null +++ b/tests/examples/UnusedPipeVariableLinter/unused_pipe.php.expect @@ -0,0 +1,7 @@ +[ + { + "blame": " htmlspecialchars($html) |> serialize($html)", + "blame_pretty": " htmlspecialchars($html) |> serialize($html)", + "description": "Missing pipe variable in right-hand side of pipe operator" + } +] diff --git a/tests/examples/UnusedPipeVariableLinter/unused_pipe.php.in b/tests/examples/UnusedPipeVariableLinter/unused_pipe.php.in new file mode 100644 index 000000000..f6cf71fd8 --- /dev/null +++ b/tests/examples/UnusedPipeVariableLinter/unused_pipe.php.in @@ -0,0 +1,5 @@ + serialize($html); +}