Skip to content

Commit

Permalink
Merge pull request #8360 from bitwise-operators/8307-operand-class-co…
Browse files Browse the repository at this point in the history
…nstants

Add BitwiseNot and BooleanNot operators to SimpleTypeInferer
  • Loading branch information
orklah committed Aug 4, 2022
2 parents 24f7920 + 9f6ce30 commit ffc8c80
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
Expand Up @@ -203,6 +203,63 @@ public static function infer(
}
}

if ($stmt instanceof PhpParser\Node\Expr\BitwiseNot) {
$stmt_expr_type = self::infer(
$codebase,
$nodes,
$stmt->expr,
$aliases,
$file_source,
$existing_class_constants,
$fq_classlike_name
);

if ($stmt_expr_type === null) {
return null;
}

$invalidTypes = clone $stmt_expr_type;
$invalidTypes->removeType('string');
$invalidTypes->removeType('int');
$invalidTypes->removeType('float');

if (!$invalidTypes->isUnionEmpty()) {
return null;
}

$types = [];
if ($stmt_expr_type->hasString()) {
$types[] = Type::getString();
}
if ($stmt_expr_type->hasInt() || $stmt_expr_type->hasFloat()) {
$types[] = Type::getInt();
}

return $types ? Type::combineUnionTypeArray($types, null) : null;
}

if ($stmt instanceof PhpParser\Node\Expr\BooleanNot) {
$stmt_expr_type = self::infer(
$codebase,
$nodes,
$stmt->expr,
$aliases,
$file_source,
$existing_class_constants,
$fq_classlike_name
);

if ($stmt_expr_type === null) {
return null;
} elseif ($stmt_expr_type->isAlwaysFalsy()) {
return Type::getTrue();
} elseif ($stmt_expr_type->isAlwaysTruthy()) {
return Type::getFalse();
} else {
return Type::getBool();
}
}

if ($stmt instanceof PhpParser\Node\Expr\ConstFetch) {
$name = strtolower($stmt->name->parts[0]);
if ($name === 'false') {
Expand Down
54 changes: 54 additions & 0 deletions tests/ConstantTest.php
Expand Up @@ -998,6 +998,60 @@ class X {
'$c' => 'int',
]
],
'bitwiseAndClassConstant' => [
'code' => '<?php
class X {
public const A = 1;
public const B = 2;
public const C = self::A & self::B;
}
$c = X::C;',
'assertions' => [
'$c' => 'int',
]
],
'bitwiseXorClassConstant' => [
'code' => '<?php
class X {
public const A = 1;
public const B = 2;
public const C = self::A ^ self::B;
}
$c = X::C;',
'assertions' => [
'$c' => 'int',
]
],
'bitwiseNotClassConstant' => [
'code' => '<?php
class X {
public const A = ~0;
public const B = ~"aa";
}
$a = X::A;
$b = X::B;',
'assertions' => [
'$a' => 'int',
'$b' => 'string',
]
],
'booleanNotClassConstant' => [
'code' => '<?php
class X {
public const A = !true;
public const B = !false;
}
$a = X::A;
$b = X::B;',
'assertions' => [
'$a' => 'false',
'$b' => 'true',
]
],
'protectedClassConstantAccessibilitySameNameInChild' => [
'code' => '<?php
class A {
Expand Down

0 comments on commit ffc8c80

Please sign in to comment.