This repository has been archived by the owner on Apr 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RFC/Proof-of-concept: Implement children declarations as a trait (#214)
* RFC: Implement children declarations as a trait Currently serializes to the same format as HackC, to allow migrating to the new syntax with no changes to validation. Some normalization is needed, as HackC emits some overly-complex structures - e.g. with `$expr = tuple(EXACTLY_ONE, EXPRESSION, $inner_expr)` can be simplified to `$expr = $inner_expr`. It is not currently in a form suitable for use - the trait I've added merely confirms that the two forms of children declaration are semanticaly equivalent. I think that's a meaningful first step; if we're happy for this, we can merge it, start on migration tools, then add an alternative trait to allow removal of the legacy syntax. This is very much a draft API; open to a complete rewrite if desired :) refs #212 * make child declaration a static method * rename trait for consistency, add new-way-only trait too * remove bogus child declaration
- Loading branch information
1 parent
cc03980
commit 83e81a3
Showing
21 changed files
with
682 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
final class Any implements Constraint { | ||
public function legacySerialize(): mixed { | ||
return 1; | ||
} | ||
|
||
public function legacySerializeAsLeaf(): (LegacyConstraintType, mixed) { | ||
return tuple(LegacyConstraintType::ANY, null); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
final class AnyNumberOf<T as Constraint> extends QuantifierConstraint<T> { | ||
const LegacyExpressionType LEGACY_EXPRESSION_TYPE = | ||
LegacyExpressionType::ANY_QUANTITY; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
use namespace HH\Lib\{C, Vec}; | ||
|
||
final class AnyOf<T as Constraint> implements LegacyExpression { | ||
private vec<T> $children; | ||
public function __construct(T $a, T $b, T ...$rest) { | ||
$this->children = Vec\concat(vec[$a, $b], $rest); | ||
} | ||
|
||
public function legacySerialize(): (LegacyExpressionType, mixed, mixed) { | ||
$it = tuple( | ||
LegacyExpressionType::EITHER, | ||
$this->children[0]->legacySerialize(), | ||
$this->children[1]->legacySerialize(), | ||
); | ||
$rest = Vec\drop($this->children, 2); | ||
while (!C\is_empty($rest)) { | ||
$it = tuple( | ||
LegacyExpressionType::EITHER, | ||
$it, | ||
$rest[0]->legacySerialize(), | ||
); | ||
$rest = Vec\drop($rest, 1); | ||
} | ||
return $it; | ||
} | ||
|
||
final public function legacySerializeAsLeaf(): null { | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
final class AtLeastOneOf<T as Constraint> extends QuantifierConstraint<T> { | ||
const LegacyExpressionType LEGACY_EXPRESSION_TYPE = | ||
LegacyExpressionType::AT_LEAST_ONE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
use namespace HH\Lib\Str; | ||
|
||
final class Category extends LeafConstraint { | ||
public function __construct(private string $category) { | ||
} | ||
|
||
public function legacySerializeAsLeaf(): (LegacyConstraintType, string) { | ||
return tuple( | ||
LegacyConstraintType::CATEGORY, | ||
$this->category | ||
|> Str\strip_prefix($$, '%') | ||
|> Str\replace($$, ':', '__') | ||
|> Str\replace($$, '-', '_'), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
interface Constraint { | ||
public function legacySerialize(): mixed; | ||
public function legacySerializeAsLeaf(): ?(LegacyConstraintType, mixed); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
abstract class LeafConstraint implements LegacyExpression { | ||
abstract public function legacySerializeAsLeaf( | ||
): (LegacyConstraintType, mixed); | ||
|
||
final public function legacySerialize( | ||
): (LegacyExpressionType, LegacyConstraintType, mixed) { | ||
$as_leaf = $this->legacySerializeAsLeaf(); | ||
return tuple(LegacyExpressionType::EXACTLY_ONE, $as_leaf[0], $as_leaf[1]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
enum LegacyConstraintType: int { | ||
ANY = 1; | ||
PCDATA = 2; | ||
CLASSNAME = 3; | ||
CATEGORY = 4; | ||
EXPRESSION = 5; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
interface LegacyExpression extends Constraint { | ||
public function legacySerialize(): (LegacyExpressionType, mixed, mixed); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
enum LegacyExpressionType: int { | ||
EXACTLY_ONE = 0; | ||
ANY_QUANTITY = 1; | ||
ZERO_OR_ONE = 2; | ||
AT_LEAST_ONE = 3; | ||
SEQUENCE = 4; | ||
EITHER = 5; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
final class None implements Constraint { | ||
public function legacySerialize(): mixed { | ||
return 0; | ||
} | ||
|
||
public function legacySerializeAsLeaf(): null { | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
final class OfType<<<__Enforceable>> reify T> extends LeafConstraint { | ||
public function legacySerializeAsLeaf(): (LegacyConstraintType, string) { | ||
return tuple( | ||
LegacyConstraintType::CLASSNAME, | ||
\HH\ReifiedGenerics\get_classname<T>(), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
final class Optional<T as Constraint> extends QuantifierConstraint<T> { | ||
const LegacyExpressionType LEGACY_EXPRESSION_TYPE = | ||
LegacyExpressionType::ZERO_OR_ONE; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
final class PCData extends LeafConstraint { | ||
public function legacySerializeAsLeaf(): (LegacyConstraintType, mixed) { | ||
return tuple(LegacyConstraintType::PCDATA, null); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
abstract class QuantifierConstraint<T as Constraint> | ||
implements LegacyExpression { | ||
abstract const LegacyExpressionType LEGACY_EXPRESSION_TYPE; | ||
|
||
final public function __construct(private T $child) {} | ||
|
||
final public function legacySerialize( | ||
): (LegacyExpressionType, mixed, mixed) { | ||
$inner = $this->child; | ||
$as_leaf = $inner->legacySerializeAsLeaf(); | ||
if ($as_leaf is nonnull) { | ||
return tuple(static::LEGACY_EXPRESSION_TYPE, $as_leaf[0], $as_leaf[1]); | ||
} | ||
|
||
return tuple( | ||
static::LEGACY_EXPRESSION_TYPE, | ||
LegacyConstraintType::EXPRESSION, | ||
$inner->legacySerialize(), | ||
); | ||
} | ||
|
||
final public function legacySerializeAsLeaf(): null { | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright (c) 2004-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\XHP\ChildValidation; | ||
|
||
use namespace HH\Lib\{C, Vec}; | ||
|
||
final class Sequence<T as Constraint> implements LegacyExpression { | ||
private vec<T> $children; | ||
|
||
public function __construct(T $a, T $b, T ...$rest) { | ||
$this->children = Vec\concat(vec[$a, $b], $rest); | ||
} | ||
|
||
public function legacySerialize(): (LegacyExpressionType, mixed, mixed) { | ||
$it = tuple( | ||
LegacyExpressionType::SEQUENCE, | ||
$this->children[0]->legacySerialize(), | ||
$this->children[1]->legacySerialize(), | ||
); | ||
$rest = Vec\drop($this->children, 2); | ||
while (!C\is_empty($rest)) { | ||
$it = tuple( | ||
LegacyExpressionType::SEQUENCE, | ||
$it, | ||
$rest[0]->legacySerialize(), | ||
); | ||
$rest = Vec\drop($rest, 1); | ||
} | ||
return $it; | ||
} | ||
|
||
public function legacySerializeAsLeaf(): null { | ||
return null; | ||
} | ||
} |
Oops, something went wrong.