summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcon <qtc-committer@nokia.com>2010-07-02 17:15:12 +0200
committercon <qtc-committer@nokia.com>2010-07-05 12:29:51 +0200
commit8da2d2e9ce060288b4701341c1768a7f234b17f5 (patch)
tree32e22d756456391e1347f0af6a7529b70a7fd705 /src
parenta69bf7b035a49b9ad2c3f3c6fd8b7044b34a9402 (diff)
downloadqt-creator-8da2d2e9ce060288b4701341c1768a7f234b17f5.tar.gz
Quick fixes converting between hex, octal, and decimal integer literals.
Diffstat (limited to 'src')
-rw-r--r--src/plugins/cppeditor/cppquickfix.cpp184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp
index 3a4f0473f5..4cb5f94435 100644
--- a/src/plugins/cppeditor/cppquickfix.cpp
+++ b/src/plugins/cppeditor/cppquickfix.cpp
@@ -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);