Phan\Analysis\BinaryOperatorFlagVisitor::visitBinaryAdd PHP Method

visitBinaryAdd() public method

public visitBinaryAdd ( ast\Node $node ) : UnionType
$node ast\Node A node to check types on
return Phan\Language\UnionType The resulting type(s) of the binary operation
    public function visitBinaryAdd(Node $node) : UnionType
    {
        $left = UnionType::fromNode($this->context, $this->code_base, $node->children['left']);
        $right = UnionType::fromNode($this->context, $this->code_base, $node->children['right']);
        // fast-track common cases
        if ($left->isType(IntType::instance()) && $right->isType(IntType::instance())) {
            return IntType::instance()->asUnionType();
        }
        // If both left and right are arrays, then this is array
        // concatenation.
        if ($left->isGenericArray() && $right->isGenericArray()) {
            if ($left->isEqualTo($right)) {
                return $left;
            }
            return ArrayType::instance()->asUnionType();
        }
        if (($left->isType(IntType::instance()) || $left->isType(FloatType::instance())) && ($right->isType(IntType::instance()) || $right->isType(FloatType::instance()))) {
            return FloatType::instance()->asUnionType();
        }
        $left_is_array = !$left->genericArrayElementTypes()->isEmpty() && $left->nonArrayTypes()->isEmpty() || $left->isType(ArrayType::instance());
        $right_is_array = !$right->genericArrayElementTypes()->isEmpty() && $right->nonArrayTypes()->isEmpty() || $right->isType(ArrayType::instance());
        if ($left_is_array && !$right->canCastToUnionType(ArrayType::instance()->asUnionType())) {
            Issue::maybeEmit($this->code_base, $this->context, Issue::TypeInvalidRightOperand, $node->lineno ?? 0);
            return new UnionType();
        } elseif ($right_is_array && !$left->canCastToUnionType(ArrayType::instance()->asUnionType())) {
            Issue::maybeEmit($this->code_base, $this->context, Issue::TypeInvalidLeftOperand, $node->lineno ?? 0);
            return new UnionType();
        } elseif ($left_is_array || $right_is_array) {
            // If it is a '+' and we know one side is an array
            // and the other is unknown, assume array
            return ArrayType::instance()->asUnionType();
        }
        return new UnionType([IntType::instance(), FloatType::instance()]);
    }