Commit 8da2d2e9 authored by con's avatar con
Browse files

Quick fixes converting between hex, octal, and decimal integer literals.

parent a69bf7b0
......@@ -1048,6 +1048,184 @@ private:
CallAST *qlatin1Call;
};
/*
Base class for converting numeric literals between decimal, octal and hex.
Does the base check for the specific ones and parses the number.
Test cases:
0xFA0Bu;
0X856A;
298.3;
199;
074;
199L;
074L;
-199;
-017;
0783; // invalid octal
0; // border case, allow only hex<->decimal
*/
class ConvertNumericLiteral: public CppQuickFixOperation
{
public:
ConvertNumericLiteral(TextEditor::BaseTextEditor *editor)
: CppQuickFixOperation(editor)
{}
virtual int match(const QList<AST *> &path)
{
literal = 0;
if (path.isEmpty())
return -1; // nothing to do
literal = path.last()->asNumericLiteral();
if (! literal)
return -1;
Token token = tokenAt(literal->asNumericLiteral()->literal_token);
if (!token.is(T_NUMERIC_LITERAL))
return -1;
numeric = token.number;
if (numeric->isDouble() || numeric->isFloat())
return -1;
// remove trailing L or U and stuff
const char * const spell = numeric->chars();
numberLength = numeric->size();
while (numberLength > 0 && (spell[numberLength-1] < '0' || spell[numberLength-1] > 'F'))
--numberLength;
if (numberLength < 1)
return -1;
// convert to number
bool valid;
value = QString::fromUtf8(spell).left(numberLength).toULong(&valid, 0);
if (!valid) // e.g. octal with digit > 7
return -1;
return path.size() - 1; // very high priority
}
virtual void createChanges()
{
ChangeSet changes;
int start = startOf(literal);
changes.replace(start, start + numberLength, replacement);
refactoringChanges()->changeFile(fileName(), changes);
}
protected:
NumericLiteralAST *literal;
const NumericLiteral *numeric;
ulong value;
int numberLength;
QString replacement;
};
/*
Convert integer literal to hex representation.
Replace
32
040
With
0x20
*/
class ConvertNumericToHex: public ConvertNumericLiteral
{
public:
ConvertNumericToHex(TextEditor::BaseTextEditor *editor)
: ConvertNumericLiteral(editor)
{}
virtual QString description() const
{
return QApplication::translate("CppTools::QuickFix", "Convert to Hexadecimal");
}
virtual int match(const QList<AST *> &path)
{
int ret = ConvertNumericLiteral::match(path);
if (ret != -1 && !numeric->isHex()) {
replacement.sprintf("0x%lX", value);
return ret;
}
return -1;
}
};
/*
Convert integer literal to octal representation.
Replace
32
0x20
With
040
*/
class ConvertNumericToOctal: public ConvertNumericLiteral
{
public:
ConvertNumericToOctal(TextEditor::BaseTextEditor *editor)
: ConvertNumericLiteral(editor)
{}
virtual QString description() const
{
return QApplication::translate("CppTools::QuickFix", "Convert to Octal");
}
virtual int match(const QList<AST *> &path)
{
int ret = ConvertNumericLiteral::match(path);
if (ret != -1 && value != 0) {
const char * const str = numeric->chars();
if (numberLength > 1 && str[0] == '0' && str[1] != 'x' && str[1] != 'X')
return -1;
replacement.sprintf("0%lo", value);
return ret;
}
return -1;
}
};
/*
Convert integer literal to decimal representation.
Replace
0x20
040
With
32
*/
class ConvertNumericToDecimal: public ConvertNumericLiteral
{
public:
ConvertNumericToDecimal(TextEditor::BaseTextEditor *editor)
: ConvertNumericLiteral(editor)
{}
virtual QString description() const
{
return QApplication::translate("CppTools::QuickFix", "Convert to Decimal");
}
virtual int match(const QList<AST *> &path)
{
int ret = ConvertNumericLiteral::match(path);
if (ret != -1 && (value != 0 || numeric->isHex())) {
const char * const str = numeric->chars();
if (numberLength > 1 && str[0] != '0')
return -1;
replacement.sprintf("%lu", value);
return ret;
}
return -1;
}
};
} // end of anonymous namespace
......@@ -1242,6 +1420,9 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
QSharedPointer<WrapStringLiteral> wrapStringLiteral(new WrapStringLiteral(editor));
QSharedPointer<CStringToNSString> wrapCString(new CStringToNSString(editor));
QSharedPointer<TranslateStringLiteral> translateCString(new TranslateStringLiteral(editor));
QSharedPointer<ConvertNumericToHex> convertNumericToHex(new ConvertNumericToHex(editor));
QSharedPointer<ConvertNumericToOctal> convertNumericToOctal(new ConvertNumericToOctal(editor));
QSharedPointer<ConvertNumericToDecimal> convertNumericToDecimal(new ConvertNumericToDecimal(editor));
quickFixOperations.append(rewriteLogicalAndOp);
quickFixOperations.append(splitIfStatementOp);
......@@ -1253,6 +1434,9 @@ QList<TextEditor::QuickFixOperation::Ptr> CppQuickFixFactory::quickFixOperations
quickFixOperations.append(flipBinaryOp);
quickFixOperations.append(wrapStringLiteral);
quickFixOperations.append(translateCString);
quickFixOperations.append(convertNumericToHex);
quickFixOperations.append(convertNumericToOctal);
quickFixOperations.append(convertNumericToDecimal);
if (editor->mimeType() == CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)
quickFixOperations.append(wrapCString);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment