Commit d91c218d authored by Leandro Melo's avatar Leandro Melo Committed by Leandro T. C. Melo
Browse files

C++: More flexibility for string representation of macros

It's now possible to get the macro definition with the actual
line breaks used on the code. This is particularly useful for
tooltips in order for them to look nice.

The preprocessor is changed so the macro also stores the breaks
positions. This doesn't seem to have any impact on performance.
In my machine, for example, the total time for parsing Creator's
source code is approx. 18100ms with or without the patch.

Change-Id: Ic7487236315c3567d26496315accdb2adfea894a
Reviewed-on: http://codereview.qt.nokia.com/4253

Reviewed-by: default avatarChristian Kamm <christian.d.kamm@nokia.com>
parent b2374640
......@@ -62,7 +62,7 @@ Macro::Macro()
_state(0)
{ }
QString Macro::toString() const
QString Macro::decoratedName() const
{
QString text;
if (f._hidden)
......@@ -85,6 +85,25 @@ QString Macro::toString() const
text += QLatin1Char(')');
}
text += QLatin1Char(' ');
text += QString::fromUtf8(_definition.constData(), _definition.size());
return text;
}
QString Macro::toString() const
{
QString text = decoratedName();
text.append(QString::fromUtf8(_definition.constData(), _definition.size()));
return text;
}
QString Macro::toStringWithLineBreaks() const
{
if (_lineBreaks.isEmpty())
return toString();
QString text = decoratedName();
QString definitionWithBreaks = QString::fromUtf8(_definition.constData(), _definition.size());
foreach (unsigned pos, _lineBreaks)
definitionWithBreaks[pos] = '\n';
text.append(definitionWithBreaks);
return text;
}
......@@ -125,13 +125,22 @@ public:
void setVariadic(bool isVariadic)
{ f._variadic = isVariadic; }
void setLineBreaks(const QList<unsigned> &breaks)
{ _lineBreaks = breaks; }
const QList<unsigned> &lineBreaks() const
{ return _lineBreaks; }
QString toString() const;
QString toStringWithLineBreaks() const;
// ### private
Macro *_next;
unsigned _hashcode;
private:
QString decoratedName() const;
struct Flags
{
unsigned _hidden: 1;
......@@ -143,6 +152,7 @@ private:
QByteArray _definition;
QVector<QByteArray> _formals;
QString _fileName;
QList<unsigned> _lineBreaks;
unsigned _line;
unsigned _offset;
unsigned _length;
......
......@@ -59,6 +59,7 @@
#include <QtDebug>
#include <algorithm>
#include <QtCore/QList>
namespace CPlusPlus {
......@@ -1227,11 +1228,33 @@ void Preprocessor::processDefine(TokenIterator firstToken, TokenIterator lastTok
// ### make me fast!
const char *startOfDefinition = startOfToken(*tk);
const char *endOfDefinition = endOfToken(lastToken[- 1]);
QByteArray definition(startOfDefinition,
endOfDefinition - startOfDefinition);
definition.replace("\\\n", " ");
definition.replace('\n', ' ');
// It could be that the start is not really before that end, so the check...
if (startOfDefinition < endOfDefinition) {
QList<unsigned> lineBreaks;
lineBreaks.reserve(4); // A reasonable guess...?
QByteArray definition;
definition.reserve(endOfDefinition - startOfDefinition);
while (startOfDefinition != endOfDefinition) {
bool replace = false;
if (*startOfDefinition == '\n'
|| (startOfDefinition + 1 != endOfDefinition
&& *startOfDefinition == '\\'
&& *(startOfDefinition + 1) == '\n')) {
replace = true;
if (*startOfDefinition != '\n')
++startOfDefinition;
}
if (replace) {
definition.append(' ');
lineBreaks.append(definition.length() - 1);
} else {
definition.append(*startOfDefinition);
}
++startOfDefinition;
}
macro.setDefinition(definition.trimmed());
macro.setLineBreaks(lineBreaks);
}
}
env->bind(macro);
......
......@@ -320,7 +320,7 @@ CppMacro::CppMacro(const Macro &macro) : CppElement()
setHelpIdCandidates(QStringList(macro.name()));
setHelpMark(macro.name());
setLink(CPPEditorWidget::Link(macro.fileName(), macro.line()));
setTooltip(macro.toString());
setTooltip(macro.toStringWithLineBreaks());
}
CppMacro::~CppMacro()
......
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