Skip to content
This repository has been archived by the owner on Dec 1, 2024. It is now read-only.

Commit

Permalink
Add linter banning PHP equality checks (#54)
Browse files Browse the repository at this point in the history
* Add linter banning PHP equality checks

* Run linter, autofix, support <>

Add linter to default linter list, run it on hhast
  • Loading branch information
fredemmott authored Jun 11, 2018
1 parent 4a65e4b commit 2837bd2
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 5 deletions.
74 changes: 74 additions & 0 deletions src/Linters/NoPHPEqualityLinter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?hh // strict
/*
* 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\Linters;

use type Facebook\HHAST\{
BinaryExpression,
EditableNode,
EqualEqualToken,
EqualEqualEqualToken,
ExclamationEqualToken,
ExclamationEqualEqualToken,
LessThanGreaterThanToken,
};
use function Facebook\HHAST\Missing;
use namespace Facebook\TypeAssert;
use namespace HH\Lib\{C, Vec};

final class NoPHPEqualityLinter
extends AutoFixingASTLinter<BinaryExpression> {
<<__Override>>
protected static function getTargetType(): classname<BinaryExpression> {
return BinaryExpression::class;
}

<<__Override>>
public function getLintErrorForNode(
BinaryExpression $expr,
vec<EditableNode> $_parents,
): ?FixableASTLintError<BinaryExpression> {
$token = $expr->getOperator();
$replacement = null;
if ($token instanceof EqualEqualToken) {
$replacement = '===';
} else if (
$token instanceof ExclamationEqualToken
|| $token instanceof LessThanGreaterThanToken) {
$replacement = '!==';
} else {
return null;
}

return new FixableASTLintError(
$this,
'Do not use PHP equality - use "'.$replacement.'" instead.',
$expr,
);
return null;
}

<<__Override>>
public function getFixedNode(BinaryExpression $expr): ?EditableNode {
$op = $expr->getOperator();
if ($op instanceof EqualEqualToken) {
$op = new EqualEqualEqualToken($op->getLeading(), $op->getTrailing());
} else if (
$op instanceof ExclamationEqualToken
|| $op instanceof LessThanGreaterThanToken
) {
$op =
new ExclamationEqualEqualToken($op->getLeading(), $op->getTrailing());
} else {
return null;
}
return $expr->withOperator($op);
}
}
4 changes: 2 additions & 2 deletions src/Linters/suppress_ast_linter_error.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ function is_linter_suppressed_in_sibling_node(
string $ignore,
): bool {
$parent = C\last($parents);
if ($parent == null) {
if ($parent === null) {
return false;
}

$sibling = C\first($parent->getChildren());
if ($sibling == null) {
if ($sibling === null) {
return false;
}

Expand Down
1 change: 1 addition & 0 deletions src/__Private/LinterCLIConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ final class LinterCLIConfig {
Linters\NoBasicAssignmentFunctionParameterLinter::class,
Linters\MustUseBracesForControlFlowLinter::class,
Linters\MustUseOverrideAttributeLinter::class,
Linters\NoPHPEqualityLinter::class,
Linters\NoWhitespaceAtEndOfLineLinter::class,
];

Expand Down
2 changes: 1 addition & 1 deletion src/__Private/codegen/CodegenSyntax.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private function generateFieldMethods(
'static',
Vec\map(
$syntax['fields'],
$inner ==> $inner['field_name'] == $underscored
$inner ==> $inner['field_name'] === $underscored
? '$value'
: '$this->_'.$inner['field_name'],
),
Expand Down
2 changes: 1 addition & 1 deletion src/__Private/codegen/CodegenTokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public function generateExtends(
$cls = 'EditableTokenWithVariableText';
} else {
foreach ($token['fields'] as $field) {
if ($field['name'] == 'text'){
if ($field['name'] === 'text'){
$cls = 'EditableTokenWithVariableText';
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/EditableNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public function findWithParents(
}
foreach ($this->getChildren() as $child) {
$result = $child->findWithParents($predicate, $new_parents);
if (\count($result) != 0) {
if (\count($result) !== 0) {
return $result;
}
}
Expand Down
29 changes: 29 additions & 0 deletions tests/NoPHPEqualityLinterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?hh // strict
/*
* 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 NoPHPEqualityLinterTest extends TestCase {
use AutoFixingLinterTestTrait<Linters\FixableASTLintError<BinaryExpression>>;

protected function getLinter(
string $file,
): Linters\NoPHPEqualityLinter{
return new Linters\NoPHPEqualityLinter($file);
}

public function getCleanExamples(): array<array<string>> {
return [
['<?hh "foo" === "bar";'],
['<?hh "foo" !== "bar";'],
['<?hh "foo" > "bar";'],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?hh // strict
/*
* 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.
*
*/

function foo(): void {
var_dump('0e123' === '0e456');
var_dump('0e123' !== '0e456');
var_dump('0e123' !== '0e456');
}
17 changes: 17 additions & 0 deletions tests/fixtures/NoPHPEqualityLinter/double_equals.php.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{
"blame": "'0e123' == '0e456'",
"blame_pretty": "'0e123' == '0e456'",
"description": "Do not use PHP equality - use \"===\" instead."
},
{
"blame": "'0e123' != '0e456'",
"blame_pretty": "'0e123' != '0e456'",
"description": "Do not use PHP equality - use \"!==\" instead."
},
{
"blame": "'0e123' <> '0e456'",
"blame_pretty": "'0e123' <> '0e456'",
"description": "Do not use PHP equality - use \"!==\" instead."
}
]
15 changes: 15 additions & 0 deletions tests/fixtures/NoPHPEqualityLinter/double_equals.php.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?hh // strict
/*
* 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.
*
*/

function foo(): void {
var_dump('0e123' == '0e456');
var_dump('0e123' != '0e456');
var_dump('0e123' <> '0e456');
}

0 comments on commit 2837bd2

Please sign in to comment.