CppEditor: binary literal support for ConvertNumericLiteral

Extend the ConvertNumeric literal quickfix to support
C++14 binary literals.

Change-Id: Ia1cf8633e80ddf7d968a881d17ce2a07c5de89d3
Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
Frank Meerkoetter
2018-09-16 21:18:45 +02:00
parent 3502a0f7f2
commit d7be70afd4

View File

@@ -66,12 +66,15 @@
#include <QFormLayout> #include <QFormLayout>
#include <QInputDialog> #include <QInputDialog>
#include <QPushButton> #include <QPushButton>
#include <QRegularExpression>
#include <QSharedPointer> #include <QSharedPointer>
#include <QStack> #include <QStack>
#include <QTextCursor> #include <QTextCursor>
#include <QTextCodec> #include <QTextCodec>
#include <bitset>
#include <cctype> #include <cctype>
#include <limits>
using namespace CPlusPlus; using namespace CPlusPlus;
using namespace CppTools; using namespace CppTools;
@@ -1478,8 +1481,14 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi
// convert to number // convert to number
bool valid; bool valid;
ulong value = QString::fromUtf8(spell).left(numberLength).toULong(&valid, 0); ulong value = 0;
if (!valid) // e.g. octal with digit > 7 const QString x = QString::fromUtf8(spell).left(numberLength);
if (x.startsWith("0b", Qt::CaseInsensitive))
value = x.midRef(2).toULong(&valid, 2);
else
value = x.toULong(&valid, 0);
if (!valid)
return; return;
const int priority = path.size() - 1; // very high priority const int priority = path.size() - 1; // very high priority
@@ -1490,6 +1499,7 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi
/* /*
Convert integer literal to hex representation. Convert integer literal to hex representation.
Replace Replace
0b100000
32 32
040 040
With With
@@ -1505,10 +1515,13 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi
} }
if (value != 0) { if (value != 0) {
if (!(numberLength > 1 && str[0] == '0' && str[1] != 'x' && str[1] != 'X')) { if (!(numberLength > 1 && str[0] == '0'
&& str[1] != 'x' && str[1] != 'X'
&& str[1] != 'b' && str[1] != 'B')) {
/* /*
Convert integer literal to octal representation. Convert integer literal to octal representation.
Replace Replace
0b100000
32 32
0x20 0x20
With With
@@ -1528,6 +1541,7 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi
/* /*
Convert integer literal to decimal representation. Convert integer literal to decimal representation.
Replace Replace
0b100000
0x20 0x20
040 040
With With
@@ -1541,6 +1555,30 @@ void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFi
result << op; result << op;
} }
} }
if (!(numberLength > 1 && str[0] == '0' && (str[1] == 'b' || str[1] == 'B'))) {
/*
Convert integer literal to binary representation.
Replace
32
0x20
040
With
0b100000
*/
QString replacement = "0b";
if (value == 0) {
replacement.append('0');
} else {
std::bitset<std::numeric_limits<decltype (value)>::digits> b(value);
QRegularExpression re("^[0]*");
replacement.append(QString::fromStdString(b.to_string()).remove(re));
}
auto op = new ConvertNumericLiteralOp(interface, start, start + numberLength, replacement);
op->setDescription(QApplication::translate("CppTools::QuickFix", "Convert to Binary"));
op->setPriority(priority);
result << op;
}
} }
namespace { namespace {