Commit c6821e8a authored by hjk's avatar hjk
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 3cfea5bb e330d966
...@@ -117,6 +117,13 @@ Macro *Environment::bind(const Macro &__macro) ...@@ -117,6 +117,13 @@ Macro *Environment::bind(const Macro &__macro)
return m; return m;
} }
void Environment::addMacros(const QList<Macro> &macros)
{
foreach (const Macro &macro, macros) {
bind(macro);
}
}
Macro *Environment::remove(const QByteArray &name) Macro *Environment::remove(const QByteArray &name)
{ {
Macro macro; Macro macro;
...@@ -127,6 +134,23 @@ Macro *Environment::remove(const QByteArray &name) ...@@ -127,6 +134,23 @@ Macro *Environment::remove(const QByteArray &name)
return bind(macro); return bind(macro);
} }
void Environment::reset()
{
if (_macros) {
qDeleteAll(firstMacro(), lastMacro());
free(_macros);
}
if (_hash)
free(_hash);
_macros = 0;
_allocated_macros = 0;
_macro_count = -1;
_hash = 0;
_hash_count = 401;
}
bool Environment::isBuiltinMacro(const QByteArray &s) const bool Environment::isBuiltinMacro(const QByteArray &s) const
{ {
if (s.length() != 8) if (s.length() != 8)
......
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#include "CPlusPlusForwardDeclarations.h" #include "CPlusPlusForwardDeclarations.h"
#include <QVector> #include <QVector>
#include <QList>
#include <QByteArray> #include <QByteArray>
namespace CPlusPlus { namespace CPlusPlus {
...@@ -89,6 +90,9 @@ public: ...@@ -89,6 +90,9 @@ public:
Macro **lastMacro() Macro **lastMacro()
{ return _macros + _macro_count + 1; } { return _macros + _macro_count + 1; }
void reset();
void addMacros(const QList<Macro> &macros);
private: private:
static unsigned hashCode(const QByteArray &s); static unsigned hashCode(const QByteArray &s);
void rehash(); void rehash();
......
...@@ -54,6 +54,11 @@ bool SimpleToken::isKeyword() const ...@@ -54,6 +54,11 @@ bool SimpleToken::isKeyword() const
return _kind >= T_FIRST_KEYWORD && _kind < T_FIRST_QT_KEYWORD; return _kind >= T_FIRST_KEYWORD && _kind < T_FIRST_QT_KEYWORD;
} }
bool SimpleToken::isComment() const
{
return _kind == T_COMMENT || _kind == T_DOXY_COMMENT;
}
SimpleLexer::SimpleLexer() SimpleLexer::SimpleLexer()
: _lastState(0), : _lastState(0),
_skipComments(false), _skipComments(false),
......
...@@ -69,6 +69,7 @@ public: ...@@ -69,6 +69,7 @@ public:
bool isLiteral() const; bool isLiteral() const;
bool isOperator() const; bool isOperator() const;
bool isKeyword() const; bool isKeyword() const;
bool isComment() const;
public: public:
int _kind; int _kind;
......
...@@ -49,6 +49,9 @@ TokenUnderCursor::~TokenUnderCursor() ...@@ -49,6 +49,9 @@ TokenUnderCursor::~TokenUnderCursor()
SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor) const SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor) const
{ {
SimpleLexer tokenize; SimpleLexer tokenize;
tokenize.setObjCEnabled(true);
tokenize.setSkipComments(false);
QTextBlock block = cursor.block(); QTextBlock block = cursor.block();
int column = cursor.columnNumber(); int column = cursor.columnNumber();
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
<glob pattern="*.c++"/> <glob pattern="*.c++"/>
<glob pattern="*.C"/> <glob pattern="*.C"/>
<glob pattern="*.inl"/> <glob pattern="*.inl"/>
<glob pattern="*.qdoc"/>
</mime-type> </mime-type>
<mime-type type="text/x-objcsrc"> <mime-type type="text/x-objcsrc">
......
...@@ -740,7 +740,9 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs) ...@@ -740,7 +740,9 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs)
<< QLatin1String(TextEditor::Constants::C_OPERATOR) << QLatin1String(TextEditor::Constants::C_OPERATOR)
<< QLatin1String(TextEditor::Constants::C_PREPROCESSOR) << QLatin1String(TextEditor::Constants::C_PREPROCESSOR)
<< QLatin1String(TextEditor::Constants::C_LABEL) << QLatin1String(TextEditor::Constants::C_LABEL)
<< QLatin1String(TextEditor::Constants::C_COMMENT); << QLatin1String(TextEditor::Constants::C_COMMENT)
<< QLatin1String(TextEditor::Constants::C_DOXYGEN_COMMENT)
<< QLatin1String(TextEditor::Constants::C_DOXYGEN_TAG);
} }
const QVector<QTextCharFormat> formats = fs.toTextCharFormats(categories); const QVector<QTextCharFormat> formats = fs.toTextCharFormats(categories);
......
...@@ -16,6 +16,7 @@ HEADERS += cppplugin.h \ ...@@ -16,6 +16,7 @@ HEADERS += cppplugin.h \
cppeditorenums.h \ cppeditorenums.h \
cppeditor_global.h \ cppeditor_global.h \
cppclasswizard.h cppclasswizard.h
SOURCES += cppplugin.cpp \ SOURCES += cppplugin.cpp \
cppeditoractionhandler.cpp \ cppeditoractionhandler.cpp \
cppeditor.cpp \ cppeditor.cpp \
...@@ -23,4 +24,5 @@ SOURCES += cppplugin.cpp \ ...@@ -23,4 +24,5 @@ SOURCES += cppplugin.cpp \
cpphoverhandler.cpp \ cpphoverhandler.cpp \
cppfilewizard.cpp \ cppfilewizard.cpp \
cppclasswizard.cpp cppclasswizard.cpp
RESOURCES += cppeditor.qrc RESOURCES += cppeditor.qrc
...@@ -51,6 +51,8 @@ enum CppFormats { ...@@ -51,6 +51,8 @@ enum CppFormats {
CppPreprocessorFormat, CppPreprocessorFormat,
CppLabelFormat, CppLabelFormat,
CppCommentFormat, CppCommentFormat,
CppDoxygenCommentFormat,
CppDoxygenTagFormat,
NumCppFormats NumCppFormats
}; };
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
***************************************************************************/ ***************************************************************************/
#include "cpphighlighter.h" #include "cpphighlighter.h"
#include <cpptools/cppdoxygen.h>
#include <Token.h> #include <Token.h>
#include <cplusplus/SimpleLexer.h> #include <cplusplus/SimpleLexer.h>
...@@ -115,23 +116,35 @@ void CppHighlighter::highlightBlock(const QString &text) ...@@ -115,23 +116,35 @@ void CppHighlighter::highlightBlock(const QString &text)
} }
bool highlightCurrentWordAsPreprocessor = highlightAsPreprocessor; bool highlightCurrentWordAsPreprocessor = highlightAsPreprocessor;
if (highlightAsPreprocessor) if (highlightAsPreprocessor)
highlightAsPreprocessor = false; highlightAsPreprocessor = false;
if (i == 0 && tk.is(T_POUND)) { if (i == 0 && tk.is(T_POUND)) {
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]); setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
highlightAsPreprocessor = true; highlightAsPreprocessor = true;
} else if (highlightCurrentWordAsPreprocessor && } else if (highlightCurrentWordAsPreprocessor &&
(tk.isKeyword() || tk.is(T_IDENTIFIER)) && isPPKeyword(tk.text())) (tk.isKeyword() || tk.is(T_IDENTIFIER)) && isPPKeyword(tk.text()))
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]); setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
else if (tk.is(T_INT_LITERAL) || tk.is(T_FLOAT_LITERAL)) else if (tk.is(T_INT_LITERAL) || tk.is(T_FLOAT_LITERAL))
setFormat(tk.position(), tk.length(), m_formats[CppNumberFormat]); setFormat(tk.position(), tk.length(), m_formats[CppNumberFormat]);
else if (tk.is(T_STRING_LITERAL) || tk.is(T_CHAR_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)) else if (tk.is(T_STRING_LITERAL) || tk.is(T_CHAR_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL))
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]); setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
else if (tk.is(T_WIDE_STRING_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL)) else if (tk.is(T_WIDE_STRING_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL))
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]); setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
else if (tk.is(T_COMMENT)) {
setFormat(tk.position(), tk.length(), m_formats[CppCommentFormat]); else if (tk.isComment()) {
if (tk.is(T_COMMENT))
setFormat(tk.position(), tk.length(), m_formats[CppCommentFormat]);
else // a doxygen comment
highlightDoxygenComment(text, tk.position(), tk.length());
// we need to insert a close comment parenthesis, if // we need to insert a close comment parenthesis, if
// - the line starts in a C Comment (initalState != 0) // - the line starts in a C Comment (initalState != 0)
// - the first token of the line is a T_COMMENT (i == 0 && tk.is(T_COMMENT)) // - the first token of the line is a T_COMMENT (i == 0 && tk.is(T_COMMENT))
...@@ -145,12 +158,16 @@ void CppHighlighter::highlightBlock(const QString &text) ...@@ -145,12 +158,16 @@ void CppHighlighter::highlightBlock(const QString &text)
// clear the initial state. // clear the initial state.
initialState = 0; initialState = 0;
} }
} else if (tk.isKeyword() || isQtKeyword(tk.text())) } else if (tk.isKeyword() || isQtKeyword(tk.text()))
setFormat(tk.position(), tk.length(), m_formats[CppKeywordFormat]); setFormat(tk.position(), tk.length(), m_formats[CppKeywordFormat]);
else if (tk.isOperator()) else if (tk.isOperator())
setFormat(tk.position(), tk.length(), m_formats[CppOperatorFormat]); setFormat(tk.position(), tk.length(), m_formats[CppOperatorFormat]);
else if (i == 0 && tokens.size() > 1 && tk.is(T_IDENTIFIER) && tokens.at(1).is(T_COLON)) else if (i == 0 && tokens.size() > 1 && tk.is(T_IDENTIFIER) && tokens.at(1).is(T_COLON))
setFormat(tk.position(), tk.length(), m_formats[CppLabelFormat]); setFormat(tk.position(), tk.length(), m_formats[CppLabelFormat]);
else if (tk.is(T_IDENTIFIER)) else if (tk.is(T_IDENTIFIER))
highlightWord(tk.text(), tk.position(), tk.length()); highlightWord(tk.text(), tk.position(), tk.length());
} }
...@@ -304,3 +321,36 @@ void CppHighlighter::highlightWord(QStringRef word, int position, int length) ...@@ -304,3 +321,36 @@ void CppHighlighter::highlightWord(QStringRef word, int position, int length)
setFormat(position, length, m_formats[CppTypeFormat]); setFormat(position, length, m_formats[CppTypeFormat]);
} }
} }
void CppHighlighter::highlightDoxygenComment(const QString &text, int position, int)
{
int initial = position;
const QChar *uc = text.unicode();
const QChar *it = uc + position;
const QTextCharFormat &format = m_formats[CppDoxygenCommentFormat];
const QTextCharFormat &kwFormat = m_formats[CppDoxygenTagFormat];
while (! it->isNull()) {
if (it->unicode() == QLatin1Char('\\') ||
it->unicode() == QLatin1Char('@')) {
++it;
const QChar *start = it;
while (it->isLetterOrNumber() || it->unicode() == '_')
++it;
int k = CppTools::classifyDoxygenTag(start, it - start);
if (k != CppTools::T_DOXY_IDENTIFIER) {
setFormat(initial, start - uc - initial, format);
setFormat(start - uc - 1, it - start + 1, kwFormat);
initial = it - uc;
}
} else
++it;
}
setFormat(initial, it - uc - initial, format);
}
...@@ -61,6 +61,10 @@ public: ...@@ -61,6 +61,10 @@ public:
private: private:
void highlightWord(QStringRef word, int position, int length); void highlightWord(QStringRef word, int position, int length);
void highlightDoxygenComment(const QString &text, int position,
int length);
bool isPPKeyword(const QStringRef &text) const; bool isPPKeyword(const QStringRef &text) const;
bool isQtKeyword(const QStringRef &text) const; bool isQtKeyword(const QStringRef &text) const;
......
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
***************************************************************************/ ***************************************************************************/
#include "cppcodecompletion.h" #include "cppcodecompletion.h"
#include "cppmodelmanager.h" #include "cppmodelmanager.h"
#include "cppdoxygen.h"
#include <Control.h> #include <Control.h>
#include <AST.h> #include <AST.h>
...@@ -371,46 +371,54 @@ static int startOfOperator(TextEditor::ITextEditable *editor, ...@@ -371,46 +371,54 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
const QChar ch3 = pos > 1 ? editor->characterAt(pos - 3) : QChar(); const QChar ch3 = pos > 1 ? editor->characterAt(pos - 3) : QChar();
int start = pos; int start = pos;
int k = T_EOF_SYMBOL;
if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) { if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) {
if (kind) k = T_DOT;
*kind = T_DOT;
--start; --start;
} else if (wantFunctionCall && ch == QLatin1Char('(')) { } else if (wantFunctionCall && ch == QLatin1Char('(')) {
if (kind) k = T_LPAREN;
*kind = T_LPAREN;
--start; --start;
} else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) { } else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
if (kind) k = T_COLON_COLON;
*kind = T_COLON_COLON;
start -= 2; start -= 2;
} else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) { } else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) {
if (kind) k = T_ARROW;
*kind = T_ARROW;
start -= 2; start -= 2;
} else if (ch2 == QLatin1Char('.') && ch == QLatin1Char('*')) { } else if (ch2 == QLatin1Char('.') && ch == QLatin1Char('*')) {
if (kind) k = T_DOT_STAR;
*kind = T_DOT_STAR;
start -= 2; start -= 2;
} else if (ch3 == QLatin1Char('-') && ch2 == QLatin1Char('>') && ch == QLatin1Char('*')) { } else if (ch3 == QLatin1Char('-') && ch2 == QLatin1Char('>') && ch == QLatin1Char('*')) {
if (kind) k = T_ARROW_STAR;
*kind = T_ARROW_STAR;
start -= 3; start -= 3;
} else if (ch == QLatin1Char('@') || ch == QLatin1Char('\\')) {
k = T_DOXY_COMMENT;
--start;
} }
if (start != pos) { if (start == pos)
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget()); return start;
QTextCursor tc(edit->textCursor());
tc.setPosition(pos); TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
static CPlusPlus::TokenUnderCursor tokenUnderCursor; QTextCursor tc(edit->textCursor());
const SimpleToken tk = tokenUnderCursor(tc); tc.setPosition(pos);
if (tk.is(T_COMMENT) || tk.isLiteral()) {
if (kind) static CPlusPlus::TokenUnderCursor tokenUnderCursor;
*kind = T_EOF_SYMBOL; const SimpleToken tk = tokenUnderCursor(tc);
return pos;
} if (k == T_DOXY_COMMENT && tk.isNot(T_DOXY_COMMENT)) {
k = T_EOF_SYMBOL;
start = pos;
} }
else if (tk.is(T_COMMENT) || tk.isLiteral()) {
k = T_EOF_SYMBOL;
start = pos;
}
if (kind)
*kind = k;
return start; return start;
} }
...@@ -457,15 +465,32 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) ...@@ -457,15 +465,32 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
ExpressionUnderCursor expressionUnderCursor; ExpressionUnderCursor expressionUnderCursor;
QString expression; QString expression;
if (m_completionOperator == T_DOXY_COMMENT) {
for (int i = 1; i < T_DOXY_LAST_TAG; ++i) {
TextEditor::CompletionItem item(this);
item.m_text.append(QString::fromLatin1(doxygenTagSpell(i)));
item.m_icon = m_icons.keywordIcon();
m_completions.append(item);
}
return m_startPosition;
}
if (m_completionOperator) { if (m_completionOperator) {
QTextCursor tc(edit->document()); QTextCursor tc(edit->document());
tc.setPosition(endOfExpression); tc.setPosition(endOfExpression);
expression = expressionUnderCursor(tc); expression = expressionUnderCursor(tc);
if (m_completionOperator == T_LPAREN) { if (m_completionOperator == T_LPAREN) {
if (expression.endsWith(QLatin1String("SIGNAL"))) if (expression.endsWith(QLatin1String("SIGNAL")))
m_completionOperator = T_SIGNAL; m_completionOperator = T_SIGNAL;
else if (expression.endsWith(QLatin1String("SLOT"))) else if (expression.endsWith(QLatin1String("SLOT")))
m_completionOperator = T_SLOT; m_completionOperator = T_SLOT;
else if (editor->position() != endOfOperator) { else if (editor->position() != endOfOperator) {
// We don't want a function completion when the cursor isn't at the opening brace // We don't want a function completion when the cursor isn't at the opening brace
expression.clear(); expression.clear();
......
This diff is collapsed.
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "cpptools_global.h"
namespace CppTools {
enum DoxygenReservedWord {
T_DOXY_IDENTIFIER,
T_DOXY_ARG,
T_DOXY_ATTENTION,
T_DOXY_AUTHOR,
T_DOXY_CALLGRAPH,
T_DOXY_CODE,
T_DOXY_DOT,
T_DOXY_ELSE,
T_DOXY_ENDCODE,
T_DOXY_ENDCOND,
T_DOXY_ENDDOT,
T_DOXY_ENDHTMLONLY,
T_DOXY_ENDIF,
T_DOXY_ENDLATEXONLY,
T_DOXY_ENDLINK,
T_DOXY_ENDMANONLY,
T_DOXY_ENDVERBATIM,
T_DOXY_ENDXMLONLY,
T_DOXY_HIDEINITIALIZER,
T_DOXY_HTMLONLY,
T_DOXY_INTERFACE,
T_DOXY_INTERNAL,
T_DOXY_INVARIANT,
T_DOXY_LATEXONLY,
T_DOXY_LI,
T_DOXY_MANONLY,
T_DOXY_N,
T_DOXY_NOSUBGROUPING,
T_DOXY_NOTE,
T_DOXY_ONLY,
T_DOXY_POST,
T_DOXY_PRE,
T_DOXY_REMARKS,
T_DOXY_RETURN,
T_DOXY_RETURNS,
T_DOXY_SA,
T_DOXY_SEE,
T_DOXY_SHOWINITIALIZER,
T_DOXY_SINCE,
T_DOXY_TEST,
T_DOXY_TODO,
T_DOXY_VERBATIM,
T_DOXY_WARNING,
T_DOXY_XMLONLY,
T_DOXY_A,
T_DOXY_ADDTOGROUP,
T_DOXY_ANCHOR,
T_DOXY_B,
T_DOXY_C,
T_DOXY_CLASS,
T_DOXY_COND,
T_DOXY_COPYDOC,
T_DOXY_DEF,
T_DOXY_DONTINCLUDE,
T_DOXY_DOTFILE,
T_DOXY_E,
T_DOXY_ELSEIF,
T_DOXY_EM,
T_DOXY_ENUM,
T_DOXY_EXAMPLE,
T_DOXY_EXCEPTION,
T_DOXY_EXCEPTIONS,