From a9cc0abc43dfd74c7af58a45035f2fc6a17830b6 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 14:39:36 +0200 Subject: [PATCH 01/15] Document bug comparison empty statements The operators `<=` and `>=` should be treated as empty. They are currently treated as assignments. --- .../comparison_empty_statements.php.autofix.expect | 8 ++++++++ .../comparison_empty_statements.php.expect | 12 ++++++++++++ .../comparison_empty_statements.php.in | 8 ++++++++ 3 files changed, 28 insertions(+) create mode 100644 tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.autofix.expect create mode 100644 tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect create mode 100644 tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.in diff --git a/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.autofix.expect b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.autofix.expect new file mode 100644 index 000000000..d11cb5e31 --- /dev/null +++ b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.autofix.expect @@ -0,0 +1,8 @@ + 4; + 3 >= 4; +} diff --git a/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect new file mode 100644 index 000000000..0bd822cc9 --- /dev/null +++ b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect @@ -0,0 +1,12 @@ +[ + { + "blame": " 3 < 4;\n", + "blame_pretty": " 3 < 4;\n", + "description": "This statement includes an expression that has no effect" + }, + { + "blame": " 3 > 4;\n", + "blame_pretty": " 3 > 4;\n", + "description": "This statement includes an expression that has no effect" + } +] diff --git a/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.in b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.in new file mode 100644 index 000000000..d11cb5e31 --- /dev/null +++ b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.in @@ -0,0 +1,8 @@ + 4; + 3 >= 4; +} From d2a9dfc06b062a41499dfca191e9ad6414333182 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 14:42:12 +0200 Subject: [PATCH 02/15] Fix false negative, `<=` and `>=` in NoEmptyStatementsLinter --- src/Linters/NoEmptyStatementsLinter.hack | 4 +--- .../comparison_empty_statements.php.expect | 10 ++++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Linters/NoEmptyStatementsLinter.hack b/src/Linters/NoEmptyStatementsLinter.hack index 3705be1a5..f23ef1ca4 100644 --- a/src/Linters/NoEmptyStatementsLinter.hack +++ b/src/Linters/NoEmptyStatementsLinter.hack @@ -131,7 +131,7 @@ final class NoEmptyStatementsLinter extends AutoFixingASTLinter { /** * Returns whether the given token is an assignment operator. * - * This list is all the types returned from ExpressionStatement::getOperator + * This list is all the types returned from BinaryExpression::getOperator * that include "Equal" and are not comparison operators (==, >=, etc.); */ private function isAssignmentOperator(Token $op): bool { @@ -140,9 +140,7 @@ final class NoEmptyStatementsLinter extends AutoFixingASTLinter { $op is CaratEqualToken || $op is DotEqualToken || $op is EqualToken || - $op is GreaterThanEqualToken || $op is GreaterThanGreaterThanEqualToken || - $op is LessThanEqualToken || $op is LessThanLessThanEqualToken || $op is MinusEqualToken || $op is PercentEqualToken || diff --git a/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect index 0bd822cc9..1fbbe0cea 100644 --- a/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect +++ b/tests/examples/NoEmptyStatementsLinter/comparison_empty_statements.php.expect @@ -4,9 +4,19 @@ "blame_pretty": " 3 < 4;\n", "description": "This statement includes an expression that has no effect" }, + { + "blame": " 3 <= 4;\n", + "blame_pretty": " 3 <= 4;\n", + "description": "This statement includes an expression that has no effect" + }, { "blame": " 3 > 4;\n", "blame_pretty": " 3 > 4;\n", "description": "This statement includes an expression that has no effect" + }, + { + "blame": " 3 >= 4;\n", + "blame_pretty": " 3 >= 4;\n", + "description": "This statement includes an expression that has no effect" } ] From 14a8feac9150e31726d1cfe4caa196bea04bee0c Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 15:05:30 +0200 Subject: [PATCH 03/15] Document bug NodeList::getChildrenOfItemsOfType() does not refine --- .../NodeListGetChildrenOfItemsOfTypeTest.hack | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/NodeListGetChildrenOfItemsOfTypeTest.hack diff --git a/tests/NodeListGetChildrenOfItemsOfTypeTest.hack b/tests/NodeListGetChildrenOfItemsOfTypeTest.hack new file mode 100644 index 000000000..10a6f166f --- /dev/null +++ b/tests/NodeListGetChildrenOfItemsOfTypeTest.hack @@ -0,0 +1,36 @@ +/* + * 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; + +use namespace HH\Lib\C; +use type Facebook\HackTest\HackTest; + +final class NodeListGetChildrenOfItemsOfTypeTest extends HackTest { + public function testRefinesType(): void { + $node_list = static::getNodeListOfItemsOfIExpression(); + $literal_expression = + $node_list->getChildrenOfItemsOfType(LiteralExpression::class) + |> C\firstx($$); + static::takesT($literal_expression); + } + + private static function getNodeListOfItemsOfIExpression( + ): NodeList> { + // NodeList(123,) + return new NodeList( + vec[new ListItem( + new LiteralExpression(new DecimalLiteralToken(null, null, '123')), + new CommaToken(null, null), + )], + ); + } + + private static function takesT<<<__Explicit>> T>(T $_): void {} +} From 99b1131d70a273bf899549c1961128c761b4fd6d Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 15:07:39 +0200 Subject: [PATCH 04/15] Fix type refinement of NodeList::getChildrenOfItemsOfType() --- src/nodes/NodeList.hack | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/nodes/NodeList.hack b/src/nodes/NodeList.hack index af6f599c8..929b0f4eb 100644 --- a/src/nodes/NodeList.hack +++ b/src/nodes/NodeList.hack @@ -49,11 +49,14 @@ final class NodeList<+Titem as Node> extends Node { public function getChildrenOfItemsOfType( classname $what, - ): vec where Titem as ListItem { + ): vec where Titem as ListItem { $out = vec[]; foreach ($this->getChildrenOfItems() as $item) { if (\is_a($item, $what)) { - $out[] = $item; + $out[] = \HH\FIXME\UNSAFE_CAST( + $item, + 'is_a($item, $what) ~= $item is T', + ); } } return $out; From f5d4890f10b8571c1b11d7c6cb3a4c2911d23755 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 15:09:39 +0200 Subject: [PATCH 05/15] Add NodeList::getChildrenOfItemsByType() This completes this list: - Node->getChildrenOfType() - Node->getDescendantsOfType() - Node->getFirstDescendantOfType() - NodeList->getChildrenOfItemsByType() --- src/nodes/NodeList.hack | 13 +++++++++++++ tests/NodeListGetChildrenOfItemsOfTypeTest.hack | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/src/nodes/NodeList.hack b/src/nodes/NodeList.hack index 929b0f4eb..7d2877a46 100644 --- a/src/nodes/NodeList.hack +++ b/src/nodes/NodeList.hack @@ -10,6 +10,7 @@ namespace Facebook\HHAST; use namespace HH\Lib\{C, Str, Vec}; +use type Facebook\HHAST\_Private\SoftDeprecated; /* HHAST_IGNORE_ALL[5624] */ final class NodeList<+Titem as Node> extends Node { @@ -47,6 +48,7 @@ final class NodeList<+Titem as Node> extends Node { return Vec\map($this->getChildren(), $child ==> $child->getItem()); } + <getChildrenOfItemsByType()')>> public function getChildrenOfItemsOfType( classname $what, ): vec where Titem as ListItem { @@ -62,6 +64,17 @@ final class NodeList<+Titem as Node> extends Node { return $out; } + public function getChildrenOfItemsByType<<<__Enforceable>> reify T as Node>( + ): vec where Titem as ListItem { + $out = vec[]; + foreach ($this->getChildrenOfItems() as $item) { + if ($item is T) { + $out[] = $item; + } + } + return $out; + } + public static function createNonEmptyListOrNull( vec $items, ): ?NodeList { diff --git a/tests/NodeListGetChildrenOfItemsOfTypeTest.hack b/tests/NodeListGetChildrenOfItemsOfTypeTest.hack index 10a6f166f..99f67fe1c 100644 --- a/tests/NodeListGetChildrenOfItemsOfTypeTest.hack +++ b/tests/NodeListGetChildrenOfItemsOfTypeTest.hack @@ -21,6 +21,14 @@ final class NodeListGetChildrenOfItemsOfTypeTest extends HackTest { static::takesT($literal_expression); } + public function testReplacementRefinesTypeToo(): void { + $node_list = static::getNodeListOfItemsOfIExpression(); + $literal_expression = + $node_list->getChildrenOfItemsByType() |> C\firstx($$); + static::takesT($literal_expression); + } + + private static function getNodeListOfItemsOfIExpression( ): NodeList> { // NodeList(123,) From 6641652a150a29ec43b25d928aa6c76e1d34c1bc Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 15:25:18 +0200 Subject: [PATCH 06/15] Remove reference in comment to createMaybeEmptyList This function does not exist anymore. --- src/nodes/NodeList.hack | 14 ++++++++++--- tests/NoParamsIsAMissingNodeTest.hack | 30 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tests/NoParamsIsAMissingNodeTest.hack diff --git a/src/nodes/NodeList.hack b/src/nodes/NodeList.hack index 7d2877a46..b80a8f34b 100644 --- a/src/nodes/NodeList.hack +++ b/src/nodes/NodeList.hack @@ -16,9 +16,17 @@ use type Facebook\HHAST\_Private\SoftDeprecated; final class NodeList<+Titem as Node> extends Node { const string SYNTAX_KIND = 'list'; /** - * Use `NodeList::createMaybeEmptyList()` or - * `NodeList::createNonEmptyListNull()` instead to be explicit - * about desired behavior. + * Use `NodeList::createMaybeEmptyList(vec[])` or `null` instead of + * `new NodeList(vec[])` if you know the vec is always empty. + * A parsed Hack AST doesn't contain empty NodeLists. + * + * Side note: Places where you'd expect to find an empty NodeList: + * ``` + * function no_params( ): void {} + * // ^ + * ``` + * The Hack parser places a "missing" node at the carat. + * HHAST uses `null` to represent them. */ <<__Override>> public function __construct( diff --git a/tests/NoParamsIsAMissingNodeTest.hack b/tests/NoParamsIsAMissingNodeTest.hack new file mode 100644 index 000000000..e5f571c78 --- /dev/null +++ b/tests/NoParamsIsAMissingNodeTest.hack @@ -0,0 +1,30 @@ +/* + * 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; + +use namespace HH\Lib\Str; +use type Facebook\HackTest\HackTest; +use function Facebook\FBExpect\expect; + +final class NoParamsIsAMissingNodeTest extends HackTest { + /** + * @see `NodeList::__construct()` + * If this test fails, don't try and fix it. + * Just remove the comment (and this test) if this ever starts failing. + */ + public function testTheFollowingCommentStaysCorrect(): void { + $_error = null; + $json = \HH\ffp_parse_string('function no_params( ): void {}') + |> \json_encode_pure($$, inout $_error); + expect($json)->toContainSubstring( + '"function_parameter_list":{"kind":"missing"}', + ); + } +} From 8176da6515d8ccd62f7735a0f770f54b95ae28f3 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 15:25:32 +0200 Subject: [PATCH 07/15] Post commit formatting --- src/nodes/NodeList.hack | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/nodes/NodeList.hack b/src/nodes/NodeList.hack index b80a8f34b..e0450411a 100644 --- a/src/nodes/NodeList.hack +++ b/src/nodes/NodeList.hack @@ -51,8 +51,9 @@ final class NodeList<+Titem as Node> extends Node { return $this->_children; } - public function getChildrenOfItems( - ): vec where Titem as ListItem { + public function getChildrenOfItems(): vec + where + Titem as ListItem { return Vec\map($this->getChildren(), $child ==> $child->getItem()); } @@ -140,7 +141,7 @@ final class NodeList<+Titem as Node> extends Node { 'source' => $source, 'offset' => $offset, 'width' => $current_position - $offset, - ) + ), ); } @@ -204,9 +205,8 @@ final class NodeList<+Titem as Node> extends Node { if (!C\contains($this->_children, $old)) { return $this; } - return new NodeList( - Vec\map($this->_children, $c ==> $c === $old ? $new : $c), - ); + return + new NodeList(Vec\map($this->_children, $c ==> $c === $old ? $new : $c)); } public function insertBefore( @@ -252,9 +252,9 @@ final class NodeList<+Titem as Node> extends Node { return new NodeList($new); } - public function withoutItemWithChild( - Tinner $inner, - ): this where Titem as ListItem { + public function withoutItemWithChild(Tinner $inner): this + where + Titem as ListItem { $new = Vec\filter($this->_children, $c ==> $c->getItem() !== $inner); if ($new === $this->_children) { return $this; From f2bca6d37fa95cd682644adf199a4af7db8bf38d Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 16:26:01 +0200 Subject: [PATCH 08/15] Lint clean --- tests/NoParamsIsAMissingNodeTest.hack | 1 - tests/NodeListGetChildrenOfItemsOfTypeTest.hack | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/NoParamsIsAMissingNodeTest.hack b/tests/NoParamsIsAMissingNodeTest.hack index e5f571c78..e98877797 100644 --- a/tests/NoParamsIsAMissingNodeTest.hack +++ b/tests/NoParamsIsAMissingNodeTest.hack @@ -9,7 +9,6 @@ namespace Facebook\HHAST; -use namespace HH\Lib\Str; use type Facebook\HackTest\HackTest; use function Facebook\FBExpect\expect; diff --git a/tests/NodeListGetChildrenOfItemsOfTypeTest.hack b/tests/NodeListGetChildrenOfItemsOfTypeTest.hack index 99f67fe1c..2c6ec9bb7 100644 --- a/tests/NodeListGetChildrenOfItemsOfTypeTest.hack +++ b/tests/NodeListGetChildrenOfItemsOfTypeTest.hack @@ -28,7 +28,6 @@ final class NodeListGetChildrenOfItemsOfTypeTest extends HackTest { static::takesT($literal_expression); } - private static function getNodeListOfItemsOfIExpression( ): NodeList> { // NodeList(123,) From e30d8a275da4bdbd38737ab0884ec6ef9ded4974 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 16:39:55 +0200 Subject: [PATCH 09/15] Lint clean (with HHClientLinter) --- src/Linters/UnusedUseClauseLinter.hack | 4 ++-- src/Linters/UseStatementWIthoutKindLinter.hack | 6 ++---- src/Migrations/HSLMigration.hack | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Linters/UnusedUseClauseLinter.hack b/src/Linters/UnusedUseClauseLinter.hack index 67be8bc1c..b63c3f186 100644 --- a/src/Linters/UnusedUseClauseLinter.hack +++ b/src/Linters/UnusedUseClauseLinter.hack @@ -55,8 +55,8 @@ final class UnusedUseClauseLinter extends AutoFixingASTLinter { $as = $name->getText(); } else { invariant($name is QualifiedName, 'Unhandled name type'); - $as = $name->getParts()->getChildrenOfItemsOfType(NameToken::class) - |> (C\lastx($$) as nonnull)->getText(); + $as = $name->getParts()->getChildrenOfItemsByType() + |> C\lastx($$)->getText(); } } if ($kind is NamespaceToken) { diff --git a/src/Linters/UseStatementWIthoutKindLinter.hack b/src/Linters/UseStatementWIthoutKindLinter.hack index f0425633f..58baf4204 100644 --- a/src/Linters/UseStatementWIthoutKindLinter.hack +++ b/src/Linters/UseStatementWIthoutKindLinter.hack @@ -55,10 +55,8 @@ final class UseStatementWithoutKindLinter extends AutoFixingASTLinter { } $name = $clause->getName(); if ($name is QualifiedName) { - return ( - C\lastx( - $name->getParts()->getChildrenOfItemsOfType(NameToken::class), - ) as nonnull + return C\lastx( + $name->getParts()->getChildrenOfItemsByType(), )->getText(); } invariant( diff --git a/src/Migrations/HSLMigration.hack b/src/Migrations/HSLMigration.hack index 1f8163ab4..79f431505 100644 --- a/src/Migrations/HSLMigration.hack +++ b/src/Migrations/HSLMigration.hack @@ -523,7 +523,7 @@ final class HSLMigration extends BaseMigration { } $found_prefix = true; foreach ($parts as $i => $token) { - if ($token?->getText() === $search[$i]) { + if ($token->getText() === $search[$i]) { continue; } $found_prefix = false; @@ -569,7 +569,7 @@ final class HSLMigration extends BaseMigration { } foreach ($parts as $i => $token) { - if ($i < 2 && $token?->getText() !== $search[$i]) { + if ($i < 2 && $token->getText() !== $search[$i]) { break; } From e5b70149e26bcce8cf9a255a38a365da050a0710 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 16:40:22 +0200 Subject: [PATCH 10/15] Post commit formatting --- src/Linters/UseStatementWIthoutKindLinter.hack | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Linters/UseStatementWIthoutKindLinter.hack b/src/Linters/UseStatementWIthoutKindLinter.hack index 58baf4204..6f6bff9cf 100644 --- a/src/Linters/UseStatementWIthoutKindLinter.hack +++ b/src/Linters/UseStatementWIthoutKindLinter.hack @@ -71,10 +71,8 @@ final class UseStatementWithoutKindLinter extends AutoFixingASTLinter { // We need to look at the full file to figure out if this should be a // `use type`, or `use namespace` $used = $this->getUnresolvedReferencedNames(); - $used_as_ns = C\any( - $names, - $name ==> C\contains($used['namespaces'], $name), - ); + $used_as_ns = + C\any($names, $name ==> C\contains($used['namespaces'], $name)); $used_as_type = C\any($names, $name ==> C\contains($used['types'], $name)); $leading = $node->getClauses()->getFirstTokenx()->getLeadingWhitespace(); @@ -92,8 +90,7 @@ final class UseStatementWithoutKindLinter extends AutoFixingASTLinter { } <<__Memoize>> - private function getUnresolvedReferencedNames( - ): shape( + private function getUnresolvedReferencedNames(): shape( 'namespaces' => keyset, 'types' => keyset, 'functions' => keyset, From 865a9d4d73bf7dc4417078ae989ded977402995e Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Wed, 24 May 2023 16:54:39 +0200 Subject: [PATCH 11/15] One (last) lint error from HHClientLinter --- src/Migrations/HSLMigration.hack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Migrations/HSLMigration.hack b/src/Migrations/HSLMigration.hack index 79f431505..df0f10487 100644 --- a/src/Migrations/HSLMigration.hack +++ b/src/Migrations/HSLMigration.hack @@ -576,7 +576,7 @@ final class HSLMigration extends BaseMigration { if ($i === 2) { // we found an HH\Lib\* use statement, add the node and suffix $nodes[] = $decl; - $ns = HslNamespace::coerce($token?->getText()); + $ns = HslNamespace::coerce($token->getText()); if ($ns !== null) { $suffixes[] = $ns; } From a693564cffbed73d789ee560a15a6972edfa3bbf Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Tue, 6 Jun 2023 22:01:36 +0200 Subject: [PATCH 12/15] Demonstrate the `() ==> constant` can not be parsed --- .../codegen/data/LambdaBody.SyntaxExample.hack | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/__Private/codegen/data/LambdaBody.SyntaxExample.hack diff --git a/src/__Private/codegen/data/LambdaBody.SyntaxExample.hack b/src/__Private/codegen/data/LambdaBody.SyntaxExample.hack new file mode 100644 index 000000000..33a8a1835 --- /dev/null +++ b/src/__Private/codegen/data/LambdaBody.SyntaxExample.hack @@ -0,0 +1,15 @@ +/* + * 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\__Private\SyntaxExamples; + +function lambda_body(): void { + () ==> Qualified\CONSTANT; + () ==> CONSTANT; + () ==> 1 + CONSTANT; +} From f5999456028520881bf53e8a53de783c760cbb68 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Tue, 6 Jun 2023 22:09:19 +0200 Subject: [PATCH 13/15] Regenerate codegen, allowing constants as lambda bodies The Package* classes were deleted by codegen. I have ignored these deletions for backwards compat. --- codegen/inferred_relationships.hack | 5 ++++- codegen/syntax/LambdaExpression.hack | 12 +++++++----- codegen/syntax/QualifiedName.hack | 7 +++++-- codegen/tokens/NameToken.hack | 7 +++++-- src/__Private/codegen/CodegenBase.hack | 5 +++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/codegen/inferred_relationships.hack b/codegen/inferred_relationships.hack index 860e3bbaf..1be8b7c31 100644 --- a/codegen/inferred_relationships.hack +++ b/codegen/inferred_relationships.hack @@ -1,7 +1,7 @@ /** * This file is generated. Do not modify it manually! * - * @generated SignedSource<> + * @generated SignedSource<<0cb6442b34479c8ca9d81ac0cc1ec48a>> */ namespace Facebook\HHAST\__Private; @@ -923,6 +923,7 @@ const dict> INFERRED_RELATIONSHIPS = dict[ 'list|list_item>', 'list>', 'list>', + 'list|list_item>', 'list|list_item>', 'list|list_item|list_item>', 'list|list_item>', @@ -2392,9 +2393,11 @@ const dict> INFERRED_RELATIONSHIPS = dict[ 'parenthesized_expression', 'postfix_unary_expression', 'prefix_unary_expression', + 'qualified_name', 'scope_resolution_expression', 'shape_expression', 'subscript_expression', + 'token:name', 'variable', 'varray_intrinsic_expression', 'vector_intrinsic_expression', diff --git a/codegen/syntax/LambdaExpression.hack b/codegen/syntax/LambdaExpression.hack index b19b9e053..01744e869 100644 --- a/codegen/syntax/LambdaExpression.hack +++ b/codegen/syntax/LambdaExpression.hack @@ -1,7 +1,7 @@ /** * This file is generated. Do not modify it manually! * - * @generated SignedSource<<29ed3005c47a47905b1ba5ef2bed0d62>> + * @generated SignedSource<> */ namespace Facebook\HHAST; use namespace Facebook\TypeAssert; @@ -319,9 +319,10 @@ final class LambdaExpression * FunctionCallExpression | IsExpression | KeysetIntrinsicExpression | * LambdaExpression | LiteralExpression | MemberSelectionExpression | * NullableAsExpression | ObjectCreationExpression | ParenthesizedExpression - * | PostfixUnaryExpression | PrefixUnaryExpression | + * | PostfixUnaryExpression | PrefixUnaryExpression | QualifiedName | * ScopeResolutionExpression | ShapeExpression | SubscriptExpression | - * VariableExpression | VarrayIntrinsicExpression | VectorIntrinsicExpression + * NameToken | VariableExpression | VarrayIntrinsicExpression | + * VectorIntrinsicExpression */ public function getBody(): ILambdaBody { return TypeAssert\instance_of(ILambdaBody::class, $this->_body); @@ -334,9 +335,10 @@ final class LambdaExpression * FunctionCallExpression | IsExpression | KeysetIntrinsicExpression | * LambdaExpression | LiteralExpression | MemberSelectionExpression | * NullableAsExpression | ObjectCreationExpression | ParenthesizedExpression - * | PostfixUnaryExpression | PrefixUnaryExpression | + * | PostfixUnaryExpression | PrefixUnaryExpression | QualifiedName | * ScopeResolutionExpression | ShapeExpression | SubscriptExpression | - * VariableExpression | VarrayIntrinsicExpression | VectorIntrinsicExpression + * NameToken | VariableExpression | VarrayIntrinsicExpression | + * VectorIntrinsicExpression */ public function getBodyx(): ILambdaBody { return $this->getBody(); diff --git a/codegen/syntax/QualifiedName.hack b/codegen/syntax/QualifiedName.hack index fd8bfb3fb..e7d624f7f 100644 --- a/codegen/syntax/QualifiedName.hack +++ b/codegen/syntax/QualifiedName.hack @@ -1,7 +1,7 @@ /** * This file is generated. Do not modify it manually! * - * @generated SignedSource<<4579cd1ceb9bff63b706f9dc72f3fd3c>> + * @generated SignedSource<<0c30f737bac86560c28df9d343ad933d>> */ namespace Facebook\HHAST; use namespace Facebook\TypeAssert; @@ -12,7 +12,10 @@ use namespace HH\Lib\Dict; <<__ConsistentConstruct>> final class QualifiedName extends Node - implements INameishNode, __Private\IWrappableWithSimpleTypeSpecifier { + implements + ILambdaBody, + INameishNode, + __Private\IWrappableWithSimpleTypeSpecifier { const string SYNTAX_KIND = 'qualified_name'; diff --git a/codegen/tokens/NameToken.hack b/codegen/tokens/NameToken.hack index da2235ab4..5a4ac6e57 100644 --- a/codegen/tokens/NameToken.hack +++ b/codegen/tokens/NameToken.hack @@ -1,13 +1,16 @@ /** * This file is generated. Do not modify it manually! * - * @generated SignedSource<<5f91cc9b0eb7b319df6d8118854d35af>> + * @generated SignedSource<<69e54ae78c68fbded1ebb524ac6284c4>> */ namespace Facebook\HHAST; final class NameToken extends TokenWithVariableText - implements INameishNode, __Private\IWrappableWithSimpleTypeSpecifier { + implements + ILambdaBody, + INameishNode, + __Private\IWrappableWithSimpleTypeSpecifier { const string KIND = 'name'; diff --git a/src/__Private/codegen/CodegenBase.hack b/src/__Private/codegen/CodegenBase.hack index 3af245e0a..6f5687978 100644 --- a/src/__Private/codegen/CodegenBase.hack +++ b/src/__Private/codegen/CodegenBase.hack @@ -217,6 +217,9 @@ abstract class CodegenBase { HHAST\ILambdaBody::class => keyset[ HHAST\IExpression::class, HHAST\CompoundStatement::class, + // Constants are not wrapped in a name expression on the RHS of `==>`. + HHAST\NameToken::class, + HHAST\QualifiedName::class, ], HHAST\ILambdaSignature::class => keyset[ HHAST\VariableExpression::class, @@ -239,8 +242,6 @@ abstract class CodegenBase { HHAST\ParameterDeclaration::class, HHAST\PropertyDeclaration::class, HHAST\LambdaExpression::class, - // HHAST\Php7AnonymousFunction::class : not valid in hack. No attributes - // if not hack ], HHAST\INameishNode::class => keyset[ HHAST\NameToken::class, From 3d6ee367cdb977faaa7d2c57c02f6dc0b6daf4a1 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Tue, 6 Jun 2023 22:10:11 +0200 Subject: [PATCH 14/15] Limit semaphore to cpu count I don't got no 32 hardware threads --- src/__Private/codegen/CodegenRelations.hack | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__Private/codegen/CodegenRelations.hack b/src/__Private/codegen/CodegenRelations.hack index 67f548218..349dbcda6 100644 --- a/src/__Private/codegen/CodegenRelations.hack +++ b/src/__Private/codegen/CodegenRelations.hack @@ -60,7 +60,7 @@ final class CodegenRelations extends CodegenBase { $relationships = new Ref(dict[]); $queue = new Async\Semaphore( - /* limit = */ 32, + \cpu_get_count(), async $file ==> { try { $links = await $this->getRelationsInFileAsync($file); From b65217dae0eb09d9c4e33d5ceed3a933a8e7ef11 Mon Sep 17 00:00:00 2001 From: Lexidor Digital <31805625+lexidor@users.noreply.github.com> Date: Tue, 6 Jun 2023 22:15:50 +0200 Subject: [PATCH 15/15] Fix lint error in syntax example --- src/__Private/codegen/data/LambdaBody.SyntaxExample.hack | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/__Private/codegen/data/LambdaBody.SyntaxExample.hack b/src/__Private/codegen/data/LambdaBody.SyntaxExample.hack index 33a8a1835..9b79c5280 100644 --- a/src/__Private/codegen/data/LambdaBody.SyntaxExample.hack +++ b/src/__Private/codegen/data/LambdaBody.SyntaxExample.hack @@ -9,7 +9,7 @@ namespace Facebook\HHAST\__Private\SyntaxExamples; function lambda_body(): void { - () ==> Qualified\CONSTANT; - () ==> CONSTANT; - () ==> 1 + CONSTANT; + $_ = () ==> Qualified\CONSTANT; + $_ = () ==> CONSTANT; + $_ = () ==> 1 + CONSTANT; }