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

Commit 83e81a3

Browse files
authored
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
1 parent cc03980 commit 83e81a3

21 files changed

+682
-5
lines changed

src/children/Any.hack

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
final class Any implements Constraint {
13+
public function legacySerialize(): mixed {
14+
return 1;
15+
}
16+
17+
public function legacySerializeAsLeaf(): (LegacyConstraintType, mixed) {
18+
return tuple(LegacyConstraintType::ANY, null);
19+
}
20+
}

src/children/AnyNumberOf.hack

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
final class AnyNumberOf<T as Constraint> extends QuantifierConstraint<T> {
13+
const LegacyExpressionType LEGACY_EXPRESSION_TYPE =
14+
LegacyExpressionType::ANY_QUANTITY;
15+
}

src/children/AnyOf.hack

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
use namespace HH\Lib\{C, Vec};
13+
14+
final class AnyOf<T as Constraint> implements LegacyExpression {
15+
private vec<T> $children;
16+
public function __construct(T $a, T $b, T ...$rest) {
17+
$this->children = Vec\concat(vec[$a, $b], $rest);
18+
}
19+
20+
public function legacySerialize(): (LegacyExpressionType, mixed, mixed) {
21+
$it = tuple(
22+
LegacyExpressionType::EITHER,
23+
$this->children[0]->legacySerialize(),
24+
$this->children[1]->legacySerialize(),
25+
);
26+
$rest = Vec\drop($this->children, 2);
27+
while (!C\is_empty($rest)) {
28+
$it = tuple(
29+
LegacyExpressionType::EITHER,
30+
$it,
31+
$rest[0]->legacySerialize(),
32+
);
33+
$rest = Vec\drop($rest, 1);
34+
}
35+
return $it;
36+
}
37+
38+
final public function legacySerializeAsLeaf(): null {
39+
return null;
40+
}
41+
}

src/children/AtLeastOneOf.hack

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
final class AtLeastOneOf<T as Constraint> extends QuantifierConstraint<T> {
13+
const LegacyExpressionType LEGACY_EXPRESSION_TYPE =
14+
LegacyExpressionType::AT_LEAST_ONE;
15+
}

src/children/Category.hack

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
use namespace HH\Lib\Str;
13+
14+
final class Category extends LeafConstraint {
15+
public function __construct(private string $category) {
16+
}
17+
18+
public function legacySerializeAsLeaf(): (LegacyConstraintType, string) {
19+
return tuple(
20+
LegacyConstraintType::CATEGORY,
21+
$this->category
22+
|> Str\strip_prefix($$, '%')
23+
|> Str\replace($$, ':', '__')
24+
|> Str\replace($$, '-', '_'),
25+
);
26+
}
27+
}

src/children/Constraint.hack

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
interface Constraint {
13+
public function legacySerialize(): mixed;
14+
public function legacySerializeAsLeaf(): ?(LegacyConstraintType, mixed);
15+
}

src/children/LeafConstraint.hack

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
abstract class LeafConstraint implements LegacyExpression {
13+
abstract public function legacySerializeAsLeaf(
14+
): (LegacyConstraintType, mixed);
15+
16+
final public function legacySerialize(
17+
): (LegacyExpressionType, LegacyConstraintType, mixed) {
18+
$as_leaf = $this->legacySerializeAsLeaf();
19+
return tuple(LegacyExpressionType::EXACTLY_ONE, $as_leaf[0], $as_leaf[1]);
20+
}
21+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
enum LegacyConstraintType: int {
13+
ANY = 1;
14+
PCDATA = 2;
15+
CLASSNAME = 3;
16+
CATEGORY = 4;
17+
EXPRESSION = 5;
18+
}

src/children/LegacyExpression.hack

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
interface LegacyExpression extends Constraint {
13+
public function legacySerialize(): (LegacyExpressionType, mixed, mixed);
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) 2004-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*
8+
*/
9+
10+
namespace Facebook\XHP\ChildValidation;
11+
12+
enum LegacyExpressionType: int {
13+
EXACTLY_ONE = 0;
14+
ANY_QUANTITY = 1;
15+
ZERO_OR_ONE = 2;
16+
AT_LEAST_ONE = 3;
17+
SEQUENCE = 4;
18+
EITHER = 5;
19+
}

0 commit comments

Comments
 (0)