Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report always false usages of is_a #440

Closed
wants to merge 1 commit into from
Closed

Conversation

b1rdex
Copy link
Contributor

@b1rdex b1rdex commented Jan 31, 2021

@ondrejmirtes
Copy link
Member

Hi, could you achieve the same behaviour by modifying IsAFunctionTypeSpecifyingExtension instead? The ImpossibleCheckTypeHelper is there to course-correct mainly "weird" information from extensions, so making the fix in IsAFunctionTypeSpecifyingExtension might be a little harder, but much more correct. Thanks.

@b1rdex
Copy link
Contributor Author

b1rdex commented Feb 7, 2021

If I understand IsAFunctionTypeSpecifyingExtension correctly, it's used to set a type of $object var. Should I implement DynamicFunctionReturnTypeExtension also or what?

@ondrejmirtes
Copy link
Member

@b1rdex Nope, just the logic of IsAFunctionTypeSpecifyingExtension needs to be modified, there's a general dynamic return type extension for type-specifying functions.

@b1rdex
Copy link
Contributor Author

b1rdex commented Feb 9, 2021

So I finally learned the thing:

return $this->typeSpecifier->create(
	$node,
	new ConstantBooleanType(false),
	$context
);

sets the function return type to false. That's what we need... But it won't generate any error message. How do I test it? I tried

if (is_a(Bar::class, Foo::class)) {
	dumpType(is_a(Bar::class, Foo::class));
}

and it dumps false w/o any errors reported on max level. Also, looks like the type specifying works only in conditional context – I tried

if ($a = is_a(Bar::class, Foo::class)) {
	dumpType($a);
}

and it dumps true which is impossible.

@staabm
Copy link
Contributor

staabm commented May 13, 2022

@ondrejmirtes I think we can close this one as well then

@staabm
Copy link
Contributor

staabm commented May 13, 2022

If I understand IsAFunctionTypeSpecifyingExtension correctly, it's used to set a type of $object var. Should I implement DynamicFunctionReturnTypeExtension also or what?

So I finally learned the thing:

return $this->typeSpecifier->create(
	$node,
	new ConstantBooleanType(false),
	$context
);

just posting the anwser here, since I also worked thru this recently:

the cited code is not correct. instead it works like this:

  • the actual type needs to be set like in
    return $this->typeSpecifier->create(
    $node->getArgs()[0]->value,
    $this->isAFunctionTypeSpecifyingHelper->determineType($objectOrClassType, $classType, $allowString, true),
    $context,
    false,
    $scope,
    );
  • the returned type is then combined with the previous type in
    if ($scope !== null) {
    if ($context->true()) {
    $resultType = TypeCombinator::intersect($scope->getType($expr), $type);
    } elseif ($context->false()) {
    $resultType = TypeCombinator::remove($scope->getType($expr), $type);
    }
    }
  • and the combination of the scope-type with the type-specified type is taken into account in
    $isAlways = $this->getHelper()->findSpecifiedType(
    $scope,
    $functionCall,
    );
    if ($isAlways === null) {
    return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType();
    }
    return new ConstantBooleanType($isAlways);

@ondrejmirtes
Copy link
Member

Implemented a different way here: #1311

@b1rdex b1rdex deleted the bug4371 branch May 16, 2022 05:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

is_a: if third argument is false then do not allow string in first argument
3 participants