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

Commit

Permalink
Support nightly builds
Browse files Browse the repository at this point in the history
This is basically a lot more strict mode
  • Loading branch information
fredemmott committed Mar 6, 2019
1 parent 49efef5 commit e82e883
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 84 deletions.
20 changes: 10 additions & 10 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 14 additions & 13 deletions src/core/ComposableElement.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?hh
<?hh // strict
/*
* Copyright (c) 2004-present, Facebook, Inc.
* All rights reserved.
Expand Down Expand Up @@ -115,6 +115,7 @@ final public function replaceChildren(XHPChild ...$children): this {
// This function has been micro-optimized
$new_children = Vector {};
foreach ($children as $xhp) {
/* HH_FIXME[4273] bogus "XHPChild always truthy" - FB T41388073 */
if ($xhp) {
if ($xhp instanceof :x:frag) {
foreach ($xhp->children as $child) {
Expand Down Expand Up @@ -149,7 +150,7 @@ final public function replaceChildren(XHPChild ...$children): this {
final public function getChildren(
?string $selector = null,
): Vector<XHPChild> {
if ($selector) {
if ($selector is string && $selector !== '') {
$children = Vector {};
if ($selector[0] == '%') {
$selector = substr($selector, 1);
Expand All @@ -161,7 +162,7 @@ final public function getChildren(
} else {
$selector = :xhp::element2class($selector);
foreach ($this->children as $child) {
if ($child instanceof $selector) {
if (is_a($child, $selector, /* allow strings = */ true)) {
$children->add($child);
}
}
Expand All @@ -182,7 +183,7 @@ final public function getChildren(
* false if there are no (matching) children
*/
final public function getFirstChild(?string $selector = null): ?XHPChild {
if (!$selector) {
if ($selector === null) {
return $this->children->get(0);
} else if ($selector[0] == '%') {
$selector = substr($selector, 1);
Expand All @@ -194,7 +195,7 @@ final public function getFirstChild(?string $selector = null): ?XHPChild {
} else {
$selector = :xhp::element2class($selector);
foreach ($this->children as $child) {
if ($child instanceof $selector) {
if (is_a($child, $selector, /* allow strings = */ true)) {
return $child;
}
}
Expand Down Expand Up @@ -228,7 +229,7 @@ final public function getLastChild(?string $selector = null): ?XHPChild {
* @param $attr attribute to fetch
* @return value
*/
final public function getAttribute(string $attr) {
final public function getAttribute(string $attr): mixed {
// Return the attribute if it's there
if ($this->attributes->containsKey($attr)) {
return $this->attributes->get($attr);
Expand Down Expand Up @@ -571,9 +572,10 @@ final protected function validateAttributeValue<T>(

case XHPAttributeType::TYPE_OBJECT:
$class = $decl->getValueClass();
if ($val instanceof $class) {
if (is_a($val, $class, true)) {
break;
}
/* HH_FIXME[4026] $class as enumname<_> */
if (enum_exists($class) && $class::isValid($val)) {
break;
}
Expand Down Expand Up @@ -647,8 +649,7 @@ final protected function validateChildren(): void {
$this->validateChildrenExpression($decl->getExpression(), 0);
if (!$ret || $ii < count($this->children)) {
if (
isset($this->children[$ii]) &&
$this->children[$ii] instanceof XHPAlwaysValidChild
($this->children[$ii] ?? null) is XHPAlwaysValidChild
) {
return;
}
Expand Down Expand Up @@ -743,7 +744,7 @@ final private function validateChildrenRule(
$class = $expr->getConstraintString();
if (
$this->children->containsKey($index) &&
$this->children->get($index) instanceof $class
is_a($this->children->get($index), $class, true)
) {
return tuple(true, $index + 1);
}
Expand All @@ -760,7 +761,7 @@ final private function validateChildrenRule(
$child = $this->children->get($index);
assert($child instanceof :xhp);
$categories = $child->__xhpCategoryDeclaration();
if (empty($categories[$category])) {
if ($categories[$category] ?? 0 === 0) {
return tuple(false, $index);
}
return tuple(true, $index + 1);
Expand Down Expand Up @@ -806,11 +807,11 @@ final public function __getChildrenDescription(): string {

final public function categoryOf(string $c): bool {
$categories = $this->__xhpCategoryDeclaration();
if (isset($categories[$c])) {
if ($categories[$c] ?? null !== null) {
return true;
}
// XHP parses the category string
$c = str_replace(array(':', '-'), array('__', '_'), $c);
return isset($categories[$c]);
return ($categories[$c] ?? null) !== null;
}
}
4 changes: 2 additions & 2 deletions src/core/ReflectionXHPClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

class ReflectionXHPClass {
public function __construct(private string $className) {
public function __construct(private classname<:x:composable-element> $className) {
invariant(
class_exists($this->className),
'Invalid class name: %s',
Expand All @@ -21,7 +21,7 @@ public function getReflectionClass(): ReflectionClass {
return new ReflectionClass($this->getClassName());
}

public function getClassName(): string {
public function getClassName(): classname<:x:composable-element> {
return $this->className;
}

Expand Down
10 changes: 5 additions & 5 deletions src/html/XHPHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,20 +153,20 @@ final public function transferAttributesToRenderedRoot(
);
}

$rootID = $root->getAttribute('id') ?: null;
$thisID = $this->getAttribute('id') ?: null;
$rootID = $root->getAttribute('id') ?? null;
$thisID = $this->getAttribute('id') ?? null;

if ($rootID && $thisID && $rootID != $thisID) {
if ($rootID !== null && $thisID !== null && $rootID != $thisID) {
throw new XHPException(
'ID Collision. '.
(:xhp::class2element(self::class)).
' has an ID '.
'of "'.
$thisID.
($thisID as arraykey).
'" but it renders into a(n) '.
(:xhp::class2element(get_class($root))).
' which has an ID of "'.
$rootID.
($rootID as arraykey).
'". The latter will get '.
'overwritten (most often unexpectedly). If you are intending for '.
'this behavior consider calling $this->removeAttribute(\'id\') '.
Expand Down
28 changes: 14 additions & 14 deletions tests/AsyncTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?hh
<?hh // strict
/*
* Copyright (c) 2004-present, Facebook, Inc.
* All rights reserved.
Expand Down Expand Up @@ -39,62 +39,62 @@ class :async:par-test extends :x:element {

attribute string label @required;

public static $log = Vector {};
public static Vector<(string, string)> $log = Vector {};

protected async function asyncRender(): Awaitable<XHPRoot> {
$label = $this->:label;
self::$log[] = [$label, 'start'];
self::$log[] = tuple($label, 'start');
await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0);
self::$log[] = [$label, 'mid'];
self::$log[] = tuple($label, 'mid');
await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0);
self::$log[] = [$label, 'finish'];
self::$log[] = tuple($label, 'finish');
return <div>{$label}</div>;
}
}

class AsyncTest extends Facebook\HackTest\HackTest {
public function testDiv() {
public function testDiv(): void {
$xhp = <async:test>Herp</async:test>;
expect($xhp->toString())->toBePHPEqual('<div>Herp</div>');
}

public function testXFrag() {
public function testXFrag(): void {
$frag = <x:frag>{1}{2}</x:frag>;
$xhp = <async:test>{$frag}</async:test>;
expect($xhp->toString())->toBePHPEqual('<div>12</div>');
}

public function testNested() {
public function testNested(): void {
$xhp = <async:test><async:test>herp derp</async:test></async:test>;
expect($xhp->toString())->toBePHPEqual('<div><div>herp derp</div></div>');
}

public function testEmpty() {
public function testEmpty(): void {
$xhp = <async:test />;
expect($xhp->toString())->toBePHPEqual('<div></div>');
}

public function testNestedEmpty() {
public function testNestedEmpty(): void {
$xhp = <async:test><async:test /></async:test>;
expect($xhp->toString())->toBePHPEqual('<div><div></div></div>');
}

public function testNestedWithNonAsyncChild() {
public function testNestedWithNonAsyncChild(): void {
$xhp = <async:test><b>BE BOLD</b></async:test>;
expect($xhp->toString())->toBePHPEqual('<div><b>BE BOLD</b></div>');
}

public function testInstanceOfInterface() {
public function testInstanceOfInterface(): void {
$xhp = <async:test><b>BE BOLD</b></async:test>;
expect($xhp)->toBeInstanceOf(XHPAwaitable::class);
}

public function parallelizationContainersProvider() {
public function parallelizationContainersProvider(): array<array<:xhp>> {
return [[<test:xfrag-wrap />], [<test:async-xfrag-wrap />]];
}

<<DataProvider('parallelizationContainersProvider')>>
public function testParallelization(:x:element $container) {
public function testParallelization(:x:element $container): void {
:async:par-test::$log = Vector {};

$a = <async:par-test label="a" />;
Expand Down
14 changes: 7 additions & 7 deletions tests/BasicsTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?hh
<?hh // strict
/*
* Copyright (c) 2004-present, Facebook, Inc.
* All rights reserved.
Expand All @@ -17,31 +17,31 @@ protected function render(): XHPRoot {
}

class BasicsTest extends Facebook\HackTest\HackTest {
public function testDivWithString() {
public function testDivWithString(): void {
$xhp =
<div>
Hello, world.
</div>;
expect($xhp->toString())->toBePHPEqual('<div> Hello, world. </div>');
}

public function testFragWithString() {
public function testFragWithString(): void {
$xhp = <x:frag>Derp</x:frag>;
expect($xhp->toString())->toBeSame('Derp');
}

public function testDivWithChild() {
public function testDivWithChild(): void {
$xhp = <div><div>Herp</div></div>;
expect($xhp->toString())->toBePHPEqual('<div><div>Herp</div></div>');
}

public function testInterpolation() {
public function testInterpolation(): void {
$x = "Herp";
$xhp = <div>{$x}</div>;
expect($xhp->toString())->toBePHPEqual('<div>Herp</div>');
}

public function testXFrag() {
public function testXFrag(): void {
$x = 'herp';
$y = 'derp';
$frag = <x:frag>{$x}{$y}</x:frag>;
Expand All @@ -50,7 +50,7 @@ public function testXFrag() {
expect($xhp->toString())->toBePHPEqual('<div>herpderp</div>');
}

public function testEscaping() {
public function testEscaping(): void {
$xhp = <div>{"foo<SCRIPT>bar"}</div>;
expect($xhp->toString())->toBePHPEqual('<div>foo&lt;SCRIPT&gt;bar</div>');
}
Expand Down
26 changes: 13 additions & 13 deletions tests/ChildRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,19 @@ public function testToString(
expect($elem->__getChildrenDeclaration())->toBeSame($expected);
}

public function toStringProvider() {
return [
[<test:any-children />, 'any'],
[<test:no-children />, 'empty'],
[<test:single-child />, '(:div)'],
[<test:optional-child />, '(:div?)'],
[<test:any-number-of-child />, '(:div*)'],
[<test:at-least-one-child />, '(:div+)'],
[<test:two-children />, '(:div,:div)'],
[<test:either-of-two-children />, '(:div|:code)'],
[<test:nested-rule />, '(:div|(:code+))'],
[<test:pcdata-child />, '(pcdata)'],
[<test:category-child />, '(%flow)'],
public function toStringProvider(): vec<(:xhp, string)> {
return vec[
tuple(<test:any-children />, 'any'),
tuple(<test:no-children />, 'empty'),
tuple(<test:single-child />, '(:div)'),
tuple(<test:optional-child />, '(:div?)'),
tuple(<test:any-number-of-child />, '(:div*)'),
tuple(<test:at-least-one-child />, '(:div+)'),
tuple(<test:two-children />, '(:div,:div)'),
tuple(<test:either-of-two-children />, '(:div|:code)'),
tuple(<test:nested-rule />, '(:div|(:code+))'),
tuple(<test:pcdata-child />, '(pcdata)'),
tuple(<test:category-child />, '(%flow)'),
];
}

Expand Down
Loading

0 comments on commit e82e883

Please sign in to comment.