TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
123 lines
4.4 KiB
123 lines
4.4 KiB
<?php
|
|
|
|
/**
|
|
* Trait composition drops an abstract requirement once a concrete method is
|
|
* available for the same name. These tests cover the validation that must
|
|
* happen before the requirement is dropped: the implementation — whether the
|
|
* class's own method or a concrete method from another trait — has to satisfy
|
|
* the abstract declaration under PHP's method variance rules.
|
|
*/
|
|
class TraitAbstractRequirementTest extends BaseTest
|
|
{
|
|
public function testClassMethodMustSatisfyAbstractTraitRequirement(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `InvalidImplementation::value()` must be compatible with `RequiresValue::value()`',
|
|
'trait_abstract_class_incompatible.php'
|
|
);
|
|
}
|
|
|
|
public function testLaterConcreteTraitMethodMustSatisfyEarlierAbstract(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `HasName::name()` must be compatible with `NeedsName::name()`',
|
|
'trait_abstract_trait_concrete_incompatible.php'
|
|
);
|
|
}
|
|
|
|
public function testEarlierConcreteTraitMethodMustSatisfyLaterAbstract(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `HasName::name()` must be compatible with `NeedsName::name()`',
|
|
'trait_abstract_trait_concrete_first_incompatible.php'
|
|
);
|
|
}
|
|
|
|
public function testStaticnessMustMatchAbstractTraitRequirement(): void
|
|
{
|
|
$this->exec(
|
|
'Cannot make non static method `RequiresValue::value()` static in class `StaticImplementation`',
|
|
'trait_abstract_static_mismatch.php'
|
|
);
|
|
}
|
|
|
|
public function testImplementationCannotRequireMoreParameters(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `GreedyImplementation::value()` must be compatible with `RequiresValue::value()`',
|
|
'trait_abstract_extra_required_param.php'
|
|
);
|
|
}
|
|
|
|
public function testReturnTypeCannotBeWidened(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `WideningImplementation::value()` must be compatible with `RequiresValue::value()`',
|
|
'trait_abstract_return_widened.php'
|
|
);
|
|
}
|
|
|
|
public function testAliasedAbstractRequirementIsValidatedAgainstClassMethod(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `AliasImplementation::renamed()` must be compatible with `RequiresValue::value()`',
|
|
'trait_abstract_alias_incompatible.php'
|
|
);
|
|
}
|
|
|
|
public function testValidVarianceIsAccepted(): void
|
|
{
|
|
// Contravariant parameters, covariant returns, extra optional
|
|
// parameters, and visibility changes are all valid ways to fulfill
|
|
// an abstract trait requirement.
|
|
$this->compile('trait_abstract_variance_ok.php');
|
|
}
|
|
|
|
public function testExplicitTraitReturnIsNotTreatedAsSelf(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `InvalidExplicitTraitReturn::make()` must be compatible with `ExplicitTraitReturnRequirement::make()`',
|
|
'trait_abstract_explicit_trait_return.php'
|
|
);
|
|
}
|
|
|
|
public function testExplicitTraitTypeInUnionIsNotTreatedAsSelf(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `InvalidExplicitTraitUnionReturn::make()` must be compatible with `ExplicitTraitUnionRequirement::make()`',
|
|
'trait_abstract_explicit_trait_union_return.php'
|
|
);
|
|
}
|
|
|
|
public function testExplicitTraitParameterIsNotTreatedAsSelf(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `InvalidExplicitTraitParameter::accept()` must be compatible with `ExplicitTraitParameterRequirement::accept()`',
|
|
'trait_abstract_explicit_trait_parameter.php'
|
|
);
|
|
}
|
|
|
|
public function testParentReturnUsesTheConsumingClassParent(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `InvalidParentReturnImplementation::make()` must be compatible with `ParentReturnRequirement::make()`',
|
|
'trait_abstract_parent_return.php'
|
|
);
|
|
}
|
|
|
|
public function testParentUnionParameterUsesTheConsumingClassParent(): void
|
|
{
|
|
$this->exec(
|
|
'Declaration of `InvalidParentParamImplementation::accept()` must be compatible with `ParentParamRequirement::accept()`',
|
|
'trait_abstract_parent_union_param.php'
|
|
);
|
|
}
|
|
|
|
public function testNestedTraitCannotResolveParentFromAnEventualConsumer(): void
|
|
{
|
|
$this->exec(
|
|
'Cannot use "parent" when current class scope has no parent',
|
|
'trait_abstract_nested_parent_unavailable.php'
|
|
);
|
|
}
|
|
}
|
|
|