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)
return m;
}
void Environment::addMacros(const QList<Macro> &macros)
{
foreach (const Macro &macro, macros) {
bind(macro);
}
}
Macro *Environment::remove(const QByteArray &name)
{
Macro macro;
......@@ -127,6 +134,23 @@ Macro *Environment::remove(const QByteArray &name)
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
{
if (s.length() != 8)
......
......@@ -56,6 +56,7 @@
#include "CPlusPlusForwardDeclarations.h"
#include <QVector>
#include <QList>
#include <QByteArray>
namespace CPlusPlus {
......@@ -89,6 +90,9 @@ public:
Macro **lastMacro()
{ return _macros + _macro_count + 1; }
void reset();
void addMacros(const QList<Macro> &macros);
private:
static unsigned hashCode(const QByteArray &s);
void rehash();
......
......@@ -54,6 +54,11 @@ bool SimpleToken::isKeyword() const
return _kind >= T_FIRST_KEYWORD && _kind < T_FIRST_QT_KEYWORD;
}
bool SimpleToken::isComment() const
{
return _kind == T_COMMENT || _kind == T_DOXY_COMMENT;
}
SimpleLexer::SimpleLexer()
: _lastState(0),
_skipComments(false),
......
......@@ -69,6 +69,7 @@ public:
bool isLiteral() const;
bool isOperator() const;
bool isKeyword() const;
bool isComment() const;
public:
int _kind;
......
......@@ -49,6 +49,9 @@ TokenUnderCursor::~TokenUnderCursor()
SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor) const
{
SimpleLexer tokenize;
tokenize.setObjCEnabled(true);
tokenize.setSkipComments(false);
QTextBlock block = cursor.block();
int column = cursor.columnNumber();
......
......@@ -43,6 +43,7 @@
<glob pattern="*.c++"/>
<glob pattern="*.C"/>
<glob pattern="*.inl"/>
<glob pattern="*.qdoc"/>
</mime-type>
<mime-type type="text/x-objcsrc">
......
......@@ -740,7 +740,9 @@ void CPPEditor::setFontSettings(const TextEditor::FontSettings &fs)
<< QLatin1String(TextEditor::Constants::C_OPERATOR)
<< QLatin1String(TextEditor::Constants::C_PREPROCESSOR)
<< 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);
......
......@@ -16,6 +16,7 @@ HEADERS += cppplugin.h \
cppeditorenums.h \
cppeditor_global.h \
cppclasswizard.h
SOURCES += cppplugin.cpp \
cppeditoractionhandler.cpp \
cppeditor.cpp \
......@@ -23,4 +24,5 @@ SOURCES += cppplugin.cpp \
cpphoverhandler.cpp \
cppfilewizard.cpp \
cppclasswizard.cpp
RESOURCES += cppeditor.qrc
......@@ -51,6 +51,8 @@ enum CppFormats {
CppPreprocessorFormat,
CppLabelFormat,
CppCommentFormat,
CppDoxygenCommentFormat,
CppDoxygenTagFormat,
NumCppFormats
};
......
......@@ -32,6 +32,7 @@
***************************************************************************/
#include "cpphighlighter.h"
#include <cpptools/cppdoxygen.h>
#include <Token.h>
#include <cplusplus/SimpleLexer.h>
......@@ -115,23 +116,35 @@ void CppHighlighter::highlightBlock(const QString &text)
}
bool highlightCurrentWordAsPreprocessor = highlightAsPreprocessor;
if (highlightAsPreprocessor)
highlightAsPreprocessor = false;
if (i == 0 && tk.is(T_POUND)) {
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
highlightAsPreprocessor = true;
} else if (highlightCurrentWordAsPreprocessor &&
(tk.isKeyword() || tk.is(T_IDENTIFIER)) && isPPKeyword(tk.text()))
setFormat(tk.position(), tk.length(), m_formats[CppPreprocessorFormat]);
else if (tk.is(T_INT_LITERAL) || tk.is(T_FLOAT_LITERAL))
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))
setFormat(tk.position(), tk.length(), m_formats[CppStringFormat]);
else if (tk.is(T_WIDE_STRING_LITERAL) || tk.is(T_WIDE_CHAR_LITERAL))
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
// - 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))
......@@ -145,12 +158,16 @@ void CppHighlighter::highlightBlock(const QString &text)
// clear the initial state.
initialState = 0;
}
} else if (tk.isKeyword() || isQtKeyword(tk.text()))
setFormat(tk.position(), tk.length(), m_formats[CppKeywordFormat]);
else if (tk.isOperator())
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))
setFormat(tk.position(), tk.length(), m_formats[CppLabelFormat]);
else if (tk.is(T_IDENTIFIER))
highlightWord(tk.text(), tk.position(), tk.length());
}
......@@ -304,3 +321,36 @@ void CppHighlighter::highlightWord(QStringRef word, int position, int length)
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:
private:
void highlightWord(QStringRef word, int position, int length);
void highlightDoxygenComment(const QString &text, int position,
int length);
bool isPPKeyword(const QStringRef &text) const;
bool isQtKeyword(const QStringRef &text) const;
......
......@@ -32,8 +32,8 @@
***************************************************************************/
#include "cppcodecompletion.h"
#include "cppmodelmanager.h"
#include "cppdoxygen.h"
#include <Control.h>
#include <AST.h>
......@@ -371,46 +371,54 @@ static int startOfOperator(TextEditor::ITextEditable *editor,
const QChar ch3 = pos > 1 ? editor->characterAt(pos - 3) : QChar();
int start = pos;
int k = T_EOF_SYMBOL;
if (ch2 != QLatin1Char('.') && ch == QLatin1Char('.')) {
if (kind)
*kind = T_DOT;
k = T_DOT;
--start;
} else if (wantFunctionCall && ch == QLatin1Char('(')) {
if (kind)
*kind = T_LPAREN;
k = T_LPAREN;
--start;
} else if (ch2 == QLatin1Char(':') && ch == QLatin1Char(':')) {
if (kind)
*kind = T_COLON_COLON;
k = T_COLON_COLON;
start -= 2;
} else if (ch2 == QLatin1Char('-') && ch == QLatin1Char('>')) {
if (kind)
*kind = T_ARROW;
k = T_ARROW;
start -= 2;
} else if (ch2 == QLatin1Char('.') && ch == QLatin1Char('*')) {
if (kind)
*kind = T_DOT_STAR;
k = T_DOT_STAR;
start -= 2;
} else if (ch3 == QLatin1Char('-') && ch2 == QLatin1Char('>') && ch == QLatin1Char('*')) {
if (kind)
*kind = T_ARROW_STAR;
k = T_ARROW_STAR;
start -= 3;
} else if (ch == QLatin1Char('@') || ch == QLatin1Char('\\')) {
k = T_DOXY_COMMENT;
--start;
}
if (start != pos) {
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
QTextCursor tc(edit->textCursor());
tc.setPosition(pos);
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
const SimpleToken tk = tokenUnderCursor(tc);
if (tk.is(T_COMMENT) || tk.isLiteral()) {
if (kind)
*kind = T_EOF_SYMBOL;
return pos;
}
if (start == pos)
return start;
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
QTextCursor tc(edit->textCursor());
tc.setPosition(pos);
static CPlusPlus::TokenUnderCursor tokenUnderCursor;
const SimpleToken tk = tokenUnderCursor(tc);
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;
}
......@@ -457,15 +465,32 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
ExpressionUnderCursor expressionUnderCursor;
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) {
QTextCursor tc(edit->document());
tc.setPosition(endOfExpression);
expression = expressionUnderCursor(tc);
if (m_completionOperator == T_LPAREN) {
if (expression.endsWith(QLatin1String("SIGNAL")))
m_completionOperator = T_SIGNAL;
else if (expression.endsWith(QLatin1String("SLOT")))
m_completionOperator = T_SLOT;
else if (editor->position() != endOfOperator) {
// We don't want a function completion when the cursor isn't at the opening brace
expression.clear();
......
/***************************************************************************
**
** 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 <QString>
#include "cppdoxygen.h"
using namespace CppTools;
/*
TODO:
~
@
$
\
#
f[
f]
f$
*/
static const char *doxy_token_spell[] = {
"identifier",
"arg",
"attention",
"author",
"callgraph",
"code",
"dot",
"else",
"endcode",
"endcond",
"enddot",
"endhtmlonly",
"endif",
"endlatexonly",
"endlink",
"endmanonly",
"endverbatim",
"endxmlonly",
"hideinitializer",
"htmlonly",
"interface",
"internal",
"invariant",
"latexonly",
"li",
"manonly",
"n",
"nosubgrouping",
"note",
"only",
"post",
"pre",
"remarks",
"return",
"returns",
"sa",
"see",
"showinitializer",
"since",
"test",
"todo",
"verbatim",
"warning",
"xmlonly",
"a",
"addtogroup",
"anchor",
"b",
"c",
"class",
"cond",
"copydoc",
"def",
"dontinclude",
"dotfile",
"e",
"elseif",
"em",
"enum",
"example",
"exception",
"exceptions",
"file",
"htmlinclude",
"if",
"ifnot",
"include",
"link",
"namespace",
"p",
"package",
"ref",
"relates",
"relatesalso",
"retval",
"throw",
"throws",
"verbinclude",
"version",
"xrefitem",
"param",
"image",
"defgroup",
"page",
"paragraph",
"section",
"struct",
"subsection",
"subsubsection",
"union",
"weakgroup",
"addindex",
"brief",
"bug",
"date",
"deprecated",
"fn",
"ingroup",
"line",
"mainpage",
"name",
"overload",
"par",
"short",
"skip",
"skipline",
"typedef",
"until",
"var",
"abstract",
"badcode",
"basename",
"bold",
"caption",
"chapter",
"codeline",
"dots",
"endabstract",
"endchapter",
"endfootnote",
"endlegalese",
"endlist",
"endomit",
"endpart",
"endquotation",
"endraw",
"endsection1",
"endsection2",
"endsection3",
"endsection4",
"endsidebar",
"endtable",
"expire",
"footnote",
"generatelist",
"granularity",
"header",
"i",
"index",
"inlineimage",
"keyword",
"l",
"legalese",
"list",
"meta",
"newcode",
"o",
"oldcode",
"omit",
"omitvalue",
"part",
"printline",
"printto",
"printuntil",
"quotation",
"quotefile",
"quotefromfile",
"quotefunction",
"raw",
"row",
"section1",
"section2",
"section3",
"section4",
"sidebar",
"skipto",
"skipuntil",
"snippet",
"sub",
"sup",
"table",
"tableofcontents",
"target",
"tt",
"underline",
"unicode",
"value",
"contentspage",
"externalpage",
"group",
"headerfile",
"indexpage",
"inheaderfile",
"macro",
"module",
"nextpage",
"previouspage",
"property",
"reimp",
"service",
"startpage",
"variable",