diff --git a/duchain/expressionvisitor.cpp b/duchain/expressionvisitor.cpp --- a/duchain/expressionvisitor.cpp +++ b/duchain/expressionvisitor.cpp @@ -733,8 +733,15 @@ void ExpressionVisitor::visitBooleanOperation(Python::BooleanOperationAst* node) { - AstDefaultVisitor::visitBooleanOperation(node); - encounter(AbstractType::Ptr(new IntegralType(IntegralType::TypeBoolean))); + ExpressionVisitor v(this); + AbstractType::Ptr result; + + for (const auto& expr : node->values) { + v.visitNode(expr); + result = Helper::mergeTypes(result, v.lastType()); + } + + encounter(result); } } diff --git a/duchain/tests/pyduchaintest.cpp b/duchain/tests/pyduchaintest.cpp --- a/duchain/tests/pyduchaintest.cpp +++ b/duchain/tests/pyduchaintest.cpp @@ -480,6 +480,7 @@ QTest::newRow("check_first_arg_class_self_0") << "class c():\n def test(self, masik):\n pass" << 0; } +// this is actually for both binary and boolean operators void PyDUChainTest::testBinaryOperatorsUnsure() { QFETCH(QString, code); @@ -504,6 +505,11 @@ QTest::newRow("check_unsure_type_1") << "class c():\n def __mul__(self, other):\n return int();\nx = c();\nx = 3;\ny = 3;\ncheckme = x * y;" << "int"; QTest::newRow("check_unsure_type_2") << "class c():\n pass;\nx = c();\nx = 3;\ny = 3;\ncheckme = x * y;" << "int"; QTest::newRow("check_unsure_type_3") << "class c():\n pass;\nclass d():\n pass;\nx = c();\nx = d();\ny = 3;\ncheckme = x * y;" << "int"; + + QTest::newRow("check_unsure_type_4") << "checkme = True or False" << "bool"; + QTest::newRow("check_unsure_type_5") << "a = 'foo'; checkme = a or 'bar';" << "str"; + QTest::newRow("check_unsure_type_6") << "class A(): pass\nclass B(): pass;\ncheckme = A() or B() or 42;" << "unsure (A, B, int)"; + }