diff options
author | Erik Verbruggen <erik.verbruggen@nokia.com> | 2010-01-18 13:47:47 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@nokia.com> | 2010-01-18 14:12:44 +0100 |
commit | bedb5d936b03465f7ba18eff799d279fe69b8a81 (patch) | |
tree | 1f7cf70dcd525a5424ebf74db017db5ff4ce150e /src/shared/qscripthighlighter | |
parent | 93144e1bf7b71877593d67ff36f4a6f0fa3d3ec6 (diff) | |
download | qt-creator-bedb5d936b03465f7ba18eff799d279fe69b8a81.tar.gz |
Moved the QScriptHighlighter & friends into the QmlJS library.
Diffstat (limited to 'src/shared/qscripthighlighter')
-rw-r--r-- | src/shared/qscripthighlighter/README | 3 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/qscripthighlighter.cpp | 268 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/qscripthighlighter.h | 84 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/qscripthighlighter.pri | 11 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/qscriptincrementalscanner.cpp | 363 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/qscriptincrementalscanner.h | 116 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/qscriptindenter.cpp | 1022 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/qscriptindenter.h | 138 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/test/main.cpp | 55 | ||||
-rw-r--r-- | src/shared/qscripthighlighter/test/test.pro | 10 |
10 files changed, 0 insertions, 2070 deletions
diff --git a/src/shared/qscripthighlighter/README b/src/shared/qscripthighlighter/README deleted file mode 100644 index 220e01228e..0000000000 --- a/src/shared/qscripthighlighter/README +++ /dev/null @@ -1,3 +0,0 @@ -Syntax highlighter for Qt script courtesy of Simon. - -Exists as a duplicate in Designer. diff --git a/src/shared/qscripthighlighter/qscripthighlighter.cpp b/src/shared/qscripthighlighter/qscripthighlighter.cpp deleted file mode 100644 index 61a9aa8ef4..0000000000 --- a/src/shared/qscripthighlighter/qscripthighlighter.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "qscripthighlighter.h" - -#include <QtCore/QSet> -#include <QtCore/QtAlgorithms> - -using namespace SharedTools; - -QScriptHighlighter::QScriptHighlighter(bool duiEnabled, QTextDocument *parent): - QSyntaxHighlighter(parent), - m_duiEnabled(duiEnabled) -{ - QVector<QTextCharFormat> rc; - rc.resize(NumFormats); - rc[NumberFormat].setForeground(Qt::blue); - rc[StringFormat].setForeground(Qt::darkGreen); - rc[TypeFormat].setForeground(Qt::darkMagenta); - rc[KeywordFormat].setForeground(Qt::darkYellow); - rc[LabelFormat].setForeground(Qt::darkRed); - rc[CommentFormat].setForeground(Qt::red); rc[CommentFormat].setFontItalic(true); - rc[PreProcessorFormat].setForeground(Qt::darkBlue); - rc[VisualWhitespace].setForeground(Qt::lightGray); // for debug: rc[VisualWhitespace].setBackground(Qt::red); - setFormats(rc); - - m_scanner.setKeywords(keywords()); -} - -bool QScriptHighlighter::isDuiEnabled() const -{ return m_duiEnabled; } - -void QScriptHighlighter::highlightBlock(const QString &text) -{ - m_scanner(text, onBlockStart()); - - QTextCharFormat emptyFormat; - int lastEnd = 0; - const QList<QScriptIncrementalScanner::Token> tokens = m_scanner.tokens(); - for (int i = 0; i < tokens.size(); ++i) { - const QScriptIncrementalScanner::Token token = tokens.at(i); - - if (token.offset != lastEnd) - setFormat(lastEnd, token.offset - lastEnd, m_formats[VisualWhitespace]); - - switch (token.kind) { - case QScriptIncrementalScanner::Token::Keyword: - setFormat(token.offset, token.length, m_formats[KeywordFormat]); - break; - - case QScriptIncrementalScanner::Token::String: - highlightWhitespace(token, text, StringFormat); - break; - - case QScriptIncrementalScanner::Token::Comment: - highlightWhitespace(token, text, CommentFormat); - break; - - case QScriptIncrementalScanner::Token::Number: - highlightWhitespace(token, text, NumberFormat); - break; - - case QScriptIncrementalScanner::Token::LeftParenthesis: - onOpeningParenthesis('(', token.offset); - break; - - case QScriptIncrementalScanner::Token::RightParenthesis: - onClosingParenthesis(')', token.offset); - break; - - case QScriptIncrementalScanner::Token::LeftBrace: - onOpeningParenthesis('{', token.offset); - break; - - case QScriptIncrementalScanner::Token::RightBrace: - onClosingParenthesis('}', token.offset); - break; - - case QScriptIncrementalScanner::Token::LeftBracket: - onOpeningParenthesis('[', token.offset); - break; - - case QScriptIncrementalScanner::Token::RightBracket: - onClosingParenthesis(']', token.offset); - break; - - case QScriptIncrementalScanner::Token::Identifier: - if (m_duiEnabled && (i + 1 != tokens.size()) && tokens.at(i + 1).kind == QScriptIncrementalScanner::Token::Colon) { - int j = i; - for (; j != -1; --j) { - const QScriptIncrementalScanner::Token &tok = tokens.at(j); - if (tok.is(QScriptIncrementalScanner::Token::Dot) || tok.is(QScriptIncrementalScanner::Token::Identifier)) { - setFormat(tok.offset, tok.length, m_formats[LabelFormat]); - } else { - break; - } - } - } else { - const QChar c = text.at(token.offset); - - if ((m_duiEnabled && c.isUpper()) || (!m_duiEnabled && c == QLatin1Char('Q'))) - setFormat(token.offset, token.length, m_formats[TypeFormat]); - else - setFormat(token.offset, token.length, emptyFormat); - } - break; - - case QScriptIncrementalScanner::Token::Colon: - if (m_duiEnabled && i > 0 && tokens.at(i - 1).kind == QScriptIncrementalScanner::Token::Identifier) - setFormat(token.offset, token.length, m_formats[LabelFormat]); - else - setFormat(token.offset, token.length, emptyFormat); - break; - - case QScriptIncrementalScanner::Token::Operator: - case QScriptIncrementalScanner::Token::Dot: - setFormat(token.offset, token.length, emptyFormat); - break; - - default: - break; - } - - lastEnd = token.end(); - } - - const int firstNonSpace = m_scanner.firstNonSpace(); - if (firstNonSpace > lastEnd) - setFormat(lastEnd, firstNonSpace - lastEnd, m_formats[VisualWhitespace]); - else if (text.length() > lastEnd) - setFormat(lastEnd, text.length() - lastEnd, m_formats[VisualWhitespace]); - - onBlockEnd(m_scanner.endState(), firstNonSpace); -} - -void QScriptHighlighter::setFormats(const QVector<QTextCharFormat> &s) -{ - Q_ASSERT(s.size() == NumFormats); - qCopy(s.constBegin(), s.constEnd(), m_formats); -} - -QSet<QString> QScriptHighlighter::keywords() -{ - QSet<QString> keywords; - - keywords << QLatin1String("Infinity"); - keywords << QLatin1String("NaN"); - keywords << QLatin1String("abstract"); - keywords << QLatin1String("boolean"); - keywords << QLatin1String("break"); - keywords << QLatin1String("byte"); - keywords << QLatin1String("case"); - keywords << QLatin1String("catch"); - keywords << QLatin1String("char"); - keywords << QLatin1String("class"); - keywords << QLatin1String("const"); - keywords << QLatin1String("constructor"); - keywords << QLatin1String("continue"); - keywords << QLatin1String("debugger"); - keywords << QLatin1String("default"); - keywords << QLatin1String("delete"); - keywords << QLatin1String("do"); - keywords << QLatin1String("double"); - keywords << QLatin1String("else"); - keywords << QLatin1String("enum"); - keywords << QLatin1String("export"); - keywords << QLatin1String("extends"); - keywords << QLatin1String("false"); - keywords << QLatin1String("final"); - keywords << QLatin1String("finally"); - keywords << QLatin1String("float"); - keywords << QLatin1String("for"); - keywords << QLatin1String("function"); - keywords << QLatin1String("goto"); - keywords << QLatin1String("if"); - keywords << QLatin1String("implements"); - keywords << QLatin1String("import"); - keywords << QLatin1String("in"); - keywords << QLatin1String("instanceof"); - keywords << QLatin1String("int"); - keywords << QLatin1String("interface"); - keywords << QLatin1String("long"); - keywords << QLatin1String("native"); - keywords << QLatin1String("new"); - keywords << QLatin1String("package"); - keywords << QLatin1String("private"); - keywords << QLatin1String("protected"); - keywords << QLatin1String("public"); - keywords << QLatin1String("return"); - keywords << QLatin1String("short"); - keywords << QLatin1String("static"); - keywords << QLatin1String("super"); - keywords << QLatin1String("switch"); - keywords << QLatin1String("synchronized"); - keywords << QLatin1String("this"); - keywords << QLatin1String("throw"); - keywords << QLatin1String("throws"); - keywords << QLatin1String("transient"); - keywords << QLatin1String("true"); - keywords << QLatin1String("try"); - keywords << QLatin1String("typeof"); - keywords << QLatin1String("undefined"); - keywords << QLatin1String("var"); - keywords << QLatin1String("void"); - keywords << QLatin1String("volatile"); - keywords << QLatin1String("while"); - keywords << QLatin1String("with"); - - return keywords; -} - -int QScriptHighlighter::onBlockStart() -{ - int state = 0; - int previousState = previousBlockState(); - if (previousState != -1) - state = previousState; - return state; -} -void QScriptHighlighter::onOpeningParenthesis(QChar, int) {} -void QScriptHighlighter::onClosingParenthesis(QChar, int) {} -void QScriptHighlighter::onBlockEnd(int state, int) { return setCurrentBlockState(state); } - -void QScriptHighlighter::highlightWhitespace(const QScriptIncrementalScanner::Token &token, const QString &text, int nonWhitespaceFormat) -{ - const QTextCharFormat normalFormat = m_formats[nonWhitespaceFormat]; - const QTextCharFormat visualSpaceFormat = m_formats[VisualWhitespace]; - - const int end = token.end(); - int index = token.offset; - - while (index != end) { - const bool isSpace = text.at(index).isSpace(); - const int start = index; - - do { ++index; } - while (index != end && text.at(index).isSpace() == isSpace); - - const int tokenLength = index - start; - setFormat(start, tokenLength, isSpace ? visualSpaceFormat : normalFormat); - } -} diff --git a/src/shared/qscripthighlighter/qscripthighlighter.h b/src/shared/qscripthighlighter/qscripthighlighter.h deleted file mode 100644 index cc5f9c7dd0..0000000000 --- a/src/shared/qscripthighlighter/qscripthighlighter.h +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#ifndef QSCRIPTSYNTAXHIGHLIGHTER_H -#define QSCRIPTSYNTAXHIGHLIGHTER_H - -#include <qscripthighlighter/qscriptincrementalscanner.h> - -#include <QtCore/QVector> -#include <QtCore/QSet> -#include <QtGui/QSyntaxHighlighter> - -namespace SharedTools { - -class QScriptHighlighter : public QSyntaxHighlighter -{ - Q_OBJECT -public: - QScriptHighlighter(bool duiEnabled = false, QTextDocument *parent = 0); - virtual void highlightBlock(const QString &text); - - enum { NumberFormat, StringFormat, TypeFormat, - KeywordFormat, PreProcessorFormat, LabelFormat, CommentFormat, - VisualWhitespace, - NumFormats }; - - bool isDuiEnabled() const; - - // MS VC 6 compatible, still. - void setFormats(const QVector<QTextCharFormat> &s); - - QTextCharFormat labelTextCharFormat() const - { return m_formats[LabelFormat]; } - - QSet<QString> keywords(); - -protected: - // The functions are notified whenever parentheses are encountered. - // Custom behaviour can be added, for example storing info for indenting. - virtual int onBlockStart(); // returns the blocks initial state - virtual void onOpeningParenthesis(QChar parenthesis, int pos); - virtual void onClosingParenthesis(QChar parenthesis, int pos); - // sets the enriched user state, or simply calls setCurrentBlockState(state); - virtual void onBlockEnd(int state, int firstNonSpace); - - virtual void highlightWhitespace(const QScriptIncrementalScanner::Token &token, const QString &text, int nonWhitespaceFormat); - -protected: - QScriptIncrementalScanner m_scanner; - -private: - bool m_duiEnabled; - QTextCharFormat m_formats[NumFormats]; -}; - -} // namespace SharedTools - -#endif // QSCRIPTSYNTAXHIGHLIGHTER_H diff --git a/src/shared/qscripthighlighter/qscripthighlighter.pri b/src/shared/qscripthighlighter/qscripthighlighter.pri deleted file mode 100644 index 97f8917113..0000000000 --- a/src/shared/qscripthighlighter/qscripthighlighter.pri +++ /dev/null @@ -1,11 +0,0 @@ -INCLUDEPATH *= $$PWD $$PWD/.. - -DEFINES += QSCRIPTHIGHLIGHTER_BUILD_LIB - -SOURCES += $$PWD/qscriptincrementalscanner.cpp -HEADERS += $$PWD/qscriptincrementalscanner.h - -contains(QT, gui) { - SOURCES += $$PWD/qscripthighlighter.cpp $$PWD/qscriptindenter.cpp - HEADERS += $$PWD/qscripthighlighter.h $$PWD/qscriptindenter.h -} diff --git a/src/shared/qscripthighlighter/qscriptincrementalscanner.cpp b/src/shared/qscripthighlighter/qscriptincrementalscanner.cpp deleted file mode 100644 index 0e5a2978bc..0000000000 --- a/src/shared/qscripthighlighter/qscriptincrementalscanner.cpp +++ /dev/null @@ -1,363 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "qscriptincrementalscanner.h" - -#include <QTextCharFormat> - -using namespace SharedTools; - -QScriptIncrementalScanner::QScriptIncrementalScanner() -{ - reset(); -} - -QScriptIncrementalScanner::~QScriptIncrementalScanner() -{} - -void QScriptIncrementalScanner::reset() -{ - m_endState = -1; - m_firstNonSpace = -1; - m_tokens.clear(); -} - -QList<QScriptIncrementalScanner::Token> QScriptIncrementalScanner::operator()(const QString &text, int startState) -{ - reset(); - - // tokens - enum TokenKind { - InputAlpha, - InputNumber, - InputAsterix, - InputSlash, - InputSpace, - InputQuotation, - InputApostrophe, - InputSep, - NumInputs - }; - - // states - enum { - StateStandard, - StateCommentStart1, // '/' - StateCCommentStart2, // '*' after a '/' - StateCppCommentStart2, // '/' after a '/' - StateCComment, // after a "/*" - StateCppComment, // after a "//" - StateCCommentEnd1, // '*' in a CppComment - StateCCommentEnd2, // '/' after a '*' in a CppComment - StateStringStart, - StateString, - StateStringEnd, - StateString2Start, - StateString2, - StateString2End, - StateNumber, - NumStates - }; - - static const uchar table[NumStates][NumInputs] = { - // InputAlpha InputNumber InputAsterix InputSlash InputSpace InputQuotation InputApostrophe InputSep - { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateStandard - { StateStandard, StateNumber, StateCCommentStart2, StateCppCommentStart2, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateCommentStart1 - { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentStart2 - { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppCommentStart2 - { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCComment - { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppComment - { StateCComment, StateCComment, StateCCommentEnd1, StateCCommentEnd2, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentEnd1 - { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateCCommentEnd2 - { StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateStringStart - { StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateString - { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateStringEnd - { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2Start - { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2 - { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard }, // StateString2End - { StateNumber, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStringStart, StateString2Start, StateStandard } // StateNumber - }; - - int state = startState; - if (text.isEmpty()) { - blockEnd(state, 0); - return m_tokens; - } - - int input = -1; - int i = 0; - bool lastWasBackSlash = false; - bool makeLastStandard = false; - - static const QString alphabeth = QLatin1String("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - static const QString mathChars = QString::fromLatin1("xXeE"); - static const QString numbers = QString::fromLatin1("0123456789"); - QChar lastChar; - - int firstNonSpace = -1; - int lastNonSpace = -1; - - forever { - const QChar qc = text.at(i); - const char c = qc.toLatin1(); - - if (lastWasBackSlash) { - input = InputSep; - } else { - switch (c) { - case '*': - input = InputAsterix; - break; - case '/': - input = InputSlash; - break; - case '"': - input = InputQuotation; - break; - case '\'': - input = InputApostrophe; - break; - case ' ': - input = InputSpace; - break; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': - if (alphabeth.contains(lastChar) && (!mathChars.contains(lastChar) || !numbers.contains(text.at(i - 1)))) { - input = InputAlpha; - } else { - if (input == InputAlpha && numbers.contains(lastChar)) - input = InputAlpha; - else - input = InputNumber; - } - break; - case '.': - if (state == StateNumber) - input = InputNumber; - else - input = InputSep; - break; - default: { - if (qc.isLetter() || c == '_') - input = InputAlpha; - else - input = InputSep; - break; - } - } - } - - if (input != InputSpace) { - if (firstNonSpace < 0) - firstNonSpace = i; - lastNonSpace = i; - } - - lastWasBackSlash = !lastWasBackSlash && c == '\\'; - - state = table[state][input]; - - switch (state) { - case StateStandard: { - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - - if (input == InputAlpha ) { - insertIdentifier(i); - } else if (input == InputSep || input == InputAsterix) { - insertCharToken(i, c); - } - - break; - } - - case StateCommentStart1: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = true; - break; - case StateCCommentStart2: - makeLastStandard = false; - insertComment(i - 1, 2); - break; - case StateCppCommentStart2: - insertComment(i - 1, 2); - makeLastStandard = false; - break; - case StateCComment: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertComment(i, 1); - break; - case StateCppComment: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertComment(i, 1); - break; - case StateCCommentEnd1: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertComment(i, 1); - break; - case StateCCommentEnd2: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertComment(i, 1); - break; - case StateStringStart: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertString(i); - break; - case StateString: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertString(i); - break; - case StateStringEnd: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertString(i); - break; - case StateString2Start: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertString(i); - break; - case StateString2: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertString(i); - break; - case StateString2End: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertString(i); - break; - case StateNumber: - if (makeLastStandard) - insertCharToken(i - 1, text.at(i - 1).toAscii()); - makeLastStandard = false; - insertNumber(i); - break; - } - - lastChar = qc; - i++; - if (i >= text.length()) - break; - } - - scanForKeywords(text); - - if (state == StateCComment - || state == StateCCommentEnd1 - || state == StateCCommentStart2 - ) { - state = StateCComment; - } else { - state = StateStandard; - } - - blockEnd(state, firstNonSpace); - - return m_tokens; -} - -void QScriptIncrementalScanner::insertToken(int start, int length, Token::Kind kind, bool forceNewToken) -{ - if (m_tokens.isEmpty() || forceNewToken) { - m_tokens.append(Token(start, length, kind)); - } else { - Token &lastToken(m_tokens.last()); - - if (lastToken.kind == kind && lastToken.end() == start) { - lastToken.length += 1; - } else { - m_tokens.append(Token(start, length, kind)); - } - } -} - -void QScriptIncrementalScanner::insertCharToken(int start, const char c) -{ - Token::Kind kind; - - switch (c) { - case '!': - case '<': - case '>': - case '+': - case '-': - case '*': - case '/': - case '%': kind = Token::Operator; break; - - case ';': kind = Token::Semicolon; break; - case ':': kind = Token::Colon; break; - case ',': kind = Token::Comma; break; - case '.': kind = Token::Dot; break; - - case '(': kind = Token::LeftParenthesis; break; - case ')': kind = Token::RightParenthesis; break; - case '{': kind = Token::LeftBrace; break; - case '}': kind = Token::RightBrace; break; - case '[': kind = Token::LeftBracket; break; - case ']': kind = Token::RightBracket; break; - - default: kind = Token::Identifier; break; - } - - insertToken(start, 1, kind, true); -} - -void QScriptIncrementalScanner::scanForKeywords(const QString &text) -{ - for (int i = 0; i < m_tokens.length(); ++i) { - Token &t(m_tokens[i]); - - if (t.kind != Token::Identifier) - continue; - - const QString id = text.mid(t.offset, t.length); - if (m_keywords.contains(id)) - t.kind = Token::Keyword; - } -} diff --git a/src/shared/qscripthighlighter/qscriptincrementalscanner.h b/src/shared/qscripthighlighter/qscriptincrementalscanner.h deleted file mode 100644 index 403a174a47..0000000000 --- a/src/shared/qscripthighlighter/qscriptincrementalscanner.h +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#ifndef QSCRIPTINCREMENTALSCANNER_H -#define QSCRIPTINCREMENTALSCANNER_H - -#include <QtCore/QList> -#include <QtCore/QSet> -#include <QtCore/QString> - -namespace SharedTools { - -class QScriptIncrementalScanner -{ -public: - - struct Token { - int offset; - int length; - enum Kind { - Keyword, - Identifier, - String, - Comment, - Number, - LeftParenthesis, - RightParenthesis, - LeftBrace, - RightBrace, - LeftBracket, - RightBracket, - Operator, - Semicolon, - Colon, - Comma, - Dot - } kind; - - inline Token(int o, int l, Kind k): offset(o), length(l), kind(k) {} - inline int begin() const { return offset; } - inline int end() const { return offset + length; } - inline bool is(int k) const { return k == kind; } - inline bool isNot(int k) const { return k != kind; } - }; - -public: - QScriptIncrementalScanner(); - virtual ~QScriptIncrementalScanner(); - - void setKeywords(const QSet<QString> keywords) - { m_keywords = keywords;; } - - void reset(); - - QList<QScriptIncrementalScanner::Token> operator()(const QString &text, int startState = 0); - - int endState() const - { return m_endState; } - - int firstNonSpace() const - { return m_firstNonSpace; } - - QList<QScriptIncrementalScanner::Token> tokens() const - { return m_tokens; } - -private: - void blockEnd(int state, int firstNonSpace) - { m_endState = state; m_firstNonSpace = firstNonSpace; } - void insertString(int start) - { insertToken(start, 1, Token::String, false); } - void insertComment(int start, int length) - { insertToken(start, length, Token::Comment, false); } - void insertCharToken(int start, const char c); - void insertIdentifier(int start) - { insertToken(start, 1, Token::Identifier, false); } - void insertNumber(int start) - { insertToken(start, 1, Token::Number, false); } - void insertToken(int start, int length, Token::Kind kind, bool forceNewToken); - void scanForKeywords(const QString &text); - -private: - QSet<QString> m_keywords; - int m_endState; - int m_firstNonSpace; - QList<QScriptIncrementalScanner::Token> m_tokens; -}; - -} // namespace SharedTools - -#endif // QSCRIPTINCREMENTALSCANNER_H diff --git a/src/shared/qscripthighlighter/qscriptindenter.cpp b/src/shared/qscripthighlighter/qscriptindenter.cpp deleted file mode 100644 index 0abaf574dc..0000000000 --- a/src/shared/qscripthighlighter/qscriptindenter.cpp +++ /dev/null @@ -1,1022 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -/* - This file is a self-contained interactive indenter for Qt Script. - - The general problem of indenting a program is ill posed. On - the one hand, an indenter has to analyze programs written in a - free-form formal language that is best described in terms of - tokens, not characters, not lines. On the other hand, indentation - applies to lines and white space characters matter, and otherwise - the programs to indent are formally invalid in general, as they - are begin edited. - - The approach taken here works line by line. We receive a program - consisting of N lines or more, and we want to compute the - indentation appropriate for the Nth line. Lines beyond the Nth - lines are of no concern to us, so for simplicity we pretend the - program has exactly N lines and we call the Nth line the "bottom - line". Typically, we have to indent the bottom line when it's - still empty, so we concentrate our analysis on the N - 1 lines - that precede. - - By inspecting the (N - 1)-th line, the (N - 2)-th line, ... - backwards, we determine the kind of the bottom line and indent it - accordingly. - - * The bottom line is a comment line. See - bottomLineStartsInCComment() and - indentWhenBottomLineStartsInCComment(). - * The bottom line is a continuation line. See isContinuationLine() - and indentForContinuationLine(). - * The bottom line is a standalone line. See - indentForStandaloneLine(). - - Certain tokens that influence the indentation, notably braces, - are looked for in the lines. This is done by simple string - comparison, without a real tokenizer. Confusing constructs such - as comments and string literals are removed beforehand. -*/ - -#include "qscriptindenter.h" -#include "qscriptincrementalscanner.h" -#include <QtDebug> - -using namespace SharedTools; - -/* - The indenter avoids getting stuck in almost infinite loops by - imposing arbitrary limits on the number of lines it analyzes when - looking for a construct. - - For example, the indenter never considers more than BigRoof lines - backwards when looking for the start of a C-style comment. -*/ -const int QScriptIndenter::SmallRoof = 40; -const int QScriptIndenter::BigRoof = 400; - -QScriptIndenter::QScriptIndenter() - : label(QRegExp(QLatin1String("^\\s*((?:case\\b([^:])+|[a-zA-Z_0-9.]+)(?:\\s+)?:)(?!:)"))), - braceX(QRegExp(QLatin1String("^\\s*\\}\\s*(?:else|catch)\\b"))), - iflikeKeyword(QRegExp(QLatin1String("\\b(?:catch|do|for|if|while|with)\\b"))) -{ - - /* - The indenter supports a few parameters: - - * ppHardwareTabSize is the size of a '\t' in your favorite editor. - * ppIndentSize is the size of an indentation, or software tab - size. - * ppContinuationIndentSize is the extra indent for a continuation - line, when there is nothing to align against on the previous - line. - * ppCommentOffset is the indentation within a C-style comment, - when it cannot be picked up. - */ - - ppHardwareTabSize = 8; - ppIndentSize = 4; - ppContinuationIndentSize = 8; - ppCommentOffset = 2; - - /* - The "linizer" is a group of functions and variables to iterate - through the source code of the program to indent. The program is - given as a list of strings, with the bottom line being the line - to indent. The actual program might contain extra lines, but - those are uninteresting and not passed over to us. - */ - - // shorthands - yyLine = 0; - yyBraceDepth = 0; - yyLeftBraceFollows = 0; -} - -QScriptIndenter::~QScriptIndenter() -{ -} - -void QScriptIndenter::setTabSize(int size) -{ - ppHardwareTabSize = size; -} - -void QScriptIndenter::setIndentSize(int size) -{ - ppIndentSize = size; - ppContinuationIndentSize = 2 * size; -} - -/* - Returns the first non-space character in the string t, or - QChar() if the string is made only of white space. -*/ -QChar QScriptIndenter::firstNonWhiteSpace(const QString &t) const -{ - int i = 0; - while (i < t.length()) { - if (!t.at(i).isSpace()) - return t.at(i); - i++; - } - return QChar(); -} - -/* - Returns true if string t is made only of white space; otherwise - returns false. -*/ -bool QScriptIndenter::isOnlyWhiteSpace(const QString &t) const -{ - return firstNonWhiteSpace(t).isNull(); -} - -/* - Assuming string t is a line, returns the column number of a given - index. Column numbers and index are identical for strings that don't - contain '\t's. -*/ -int QScriptIndenter::columnForIndex(const QString &t, int index) const -{ - int col = 0; - if (index > t.length()) - index = t.length(); - - for (int i = 0; i < index; i++) { - if (t.at(i) == QLatin1Char('\t')) { - col = ((col / ppHardwareTabSize) + 1) * ppHardwareTabSize; - } else { - col++; - } - } - return col; -} - -/* - Returns the indentation size of string t. -*/ -int QScriptIndenter::indentOfLine(const QString &t) const -{ - return columnForIndex(t, t.indexOf(firstNonWhiteSpace(t))); -} - -/* - Replaces t[k] by ch, unless t[k] is '\t'. Tab characters are better - left alone since they break the "index equals column" rule. No - provisions are taken against '\n' or '\r', which shouldn't occur in - t anyway. -*/ -void QScriptIndenter::eraseChar(QString &t, int k, QChar ch) const -{ - if (t.at(k) != QLatin1Char('\t')) - t[k] = ch; -} - -/* - Removes some nefast constructs from a code line and returns the - resulting line. -*/ -QString QScriptIndenter::trimmedCodeLine(const QString &t) -{ - QScriptIncrementalScanner scanner; - - QTextBlock currentLine = yyLinizerState.iter; - int startState = qMax(0, currentLine.previous().userState()) & 0xff; - - yyLinizerState.tokens = scanner(t, startState); - QString trimmed; - int previousTokenEnd = 0; - foreach (const QScriptIncrementalScanner::Token &token, yyLinizerState.tokens) { - trimmed.append(t.midRef(previousTokenEnd, token.begin() - previousTokenEnd)); - - if (token.is(QScriptIncrementalScanner::Token::String)) { - for (int i = 0; i < token.length; ++i) - trimmed.append(QLatin1Char('X')); - - } else if (token.is(QScriptIncrementalScanner::Token::Comment)) { - for (int i = 0; i < token.length; ++i) - trimmed.append(QLatin1Char(' ')); - - } else { - trimmed.append(t.midRef(token.offset, token.length)); - } - - previousTokenEnd = token.end(); - } - - int index = yyLinizerState.tokens.size() - 1; - for (; index != -1; --index) { - const QScriptIncrementalScanner::Token &token = yyLinizerState.tokens.at(index); - if (token.isNot(QScriptIncrementalScanner::Token::Comment)) - break; - } - - bool isBinding = false; - foreach (const QScriptIncrementalScanner::Token &token, yyLinizerState.tokens) { - if (token.is(QScriptIncrementalScanner::Token::Colon)) { - isBinding = true; - break; - } - } - - if (index != -1) { - const QScriptIncrementalScanner::Token &last = yyLinizerState.tokens.at(index); - - switch (last.kind) { - case QScriptIncrementalScanner::Token::LeftParenthesis: - case QScriptIncrementalScanner::Token::LeftBrace: - case QScriptIncrementalScanner::Token::Semicolon: - case QScriptIncrementalScanner::Token::Operator: - break; - - case QScriptIncrementalScanner::Token::RightParenthesis: - case QScriptIncrementalScanner::Token::RightBrace: - if (isBinding) - trimmed.append(QLatin1Char(';')); - break; - - case QScriptIncrementalScanner::Token::Colon: - case QScriptIncrementalScanner::Token::LeftBracket: - case QScriptIncrementalScanner::Token::RightBracket: - trimmed.append(QLatin1Char(';')); - break; - - case QScriptIncrementalScanner::Token::Identifier: - case QScriptIncrementalScanner::Token::Keyword: - if (t.midRef(last.offset, last.length) != QLatin1String("else")) - trimmed.append(QLatin1Char(';')); - break; - - default: - trimmed.append(QLatin1Char(';')); - break; - } // end of switch - } - - return trimmed; -} - -/* - Returns '(' if the last parenthesis is opening, ')' if it is - closing, and QChar() if there are no parentheses in t. -*/ -QChar QScriptIndenter::lastParen(const QString &t) const -{ - int i = t.length(); - while (i > 0) { - i--; - if (t.at(i) == QLatin1Char('(') || t.at(i) == QLatin1Char(')')) - return t.at(i); - } - return QChar(); -} - -/* - Returns true if typedIn the same as okayCh or is null; otherwise - returns false. -*/ -bool QScriptIndenter::okay(QChar typedIn, QChar okayCh) const -{ - return typedIn == QChar() || typedIn == okayCh; -} - -/* - Saves and restores the state of the global linizer. This enables - backtracking. -*/ -#define YY_SAVE() LinizerState savedState = yyLinizerState -#define YY_RESTORE() yyLinizerState = savedState - -/* - Advances to the previous line in yyProgram and update yyLine - accordingly. yyLine is cleaned from comments and other damageable - constructs. Empty lines are skipped. -*/ -bool QScriptIndenter::readLine() -{ - int k; - - yyLinizerState.leftBraceFollows = - (firstNonWhiteSpace(yyLinizerState.line) == QLatin1Char('{')); - - do { - if (yyLinizerState.iter == yyProgram.firstBlock()) { - yyLinizerState.line.clear(); - return false; - } - - yyLinizerState.iter = yyLinizerState.iter.previous(); - yyLinizerState.line = yyLinizerState.iter.text(); - - yyLinizerState.line = trimmedCodeLine(yyLinizerState.line); - - /* - Remove preprocessor directives. - */ - k = 0; - while (k < yyLinizerState.line.length()) { - const QChar ch = yyLinizerState.line.at(k); - if (ch == QLatin1Char('#')) { - yyLinizerState.line.clear(); - } else if (!ch.isSpace()) { - break; - } - k++; - } - - /* - Remove trailing spaces. - */ - k = yyLinizerState.line.length(); - while (k > 0 && yyLinizerState.line.at(k - 1).isSpace()) - k--; - yyLinizerState.line.truncate(k); - - /* - '}' increment the brace depth and '{' decrements it and not - the other way around, as we are parsing backwards. - */ - yyLinizerState.braceDepth += - yyLinizerState.line.count('}') - - yyLinizerState.line.count('{'); - - /* - We use a dirty trick for - - } else ... - - We don't count the '}' yet, so that it's more or less - equivalent to the friendly construct - - } - else ... - */ - if (yyLinizerState.pendingRightBrace) - yyLinizerState.braceDepth++; - yyLinizerState.pendingRightBrace = - (yyLinizerState.line.indexOf(braceX) == 0); - if (yyLinizerState.pendingRightBrace) - yyLinizerState.braceDepth--; - } while (yyLinizerState.line.isEmpty()); - - return true; -} - -/* - Resets the linizer to its initial state, with yyLine containing the - line above the bottom line of the program. -*/ -void QScriptIndenter::startLinizer() -{ - yyLinizerState.braceDepth = 0; - yyLinizerState.pendingRightBrace = false; - - yyLine = &yyLinizerState.line; - yyBraceDepth = &yyLinizerState.braceDepth; - yyLeftBraceFollows = &yyLinizerState.leftBraceFollows; - - yyLinizerState.iter = yyProgram.lastBlock(); - yyLinizerState.iter = yyLinizerState.iter.previous(); - yyLinizerState.line = yyLinizerState.iter.text(); - readLine(); -} - -/* - Returns true if the start of the bottom line of yyProgram (and - potentially the whole line) is part of a C-style comment; - otherwise returns false. -*/ -bool QScriptIndenter::bottomLineStartsInMultilineComment() -{ - QTextBlock currentLine = yyProgram.lastBlock().previous(); - QTextBlock previousLine = currentLine.previous(); - - int startState = qMax(0, previousLine.userState()) & 0xff; - if (startState > 0) - return true; - - return false; -} - -/* - Returns the recommended indent for the bottom line of yyProgram - assuming that it starts in a C-style comment, a condition that is - tested elsewhere. - - Essentially, we're trying to align against some text on the - previous line. -*/ -int QScriptIndenter::indentWhenBottomLineStartsInMultiLineComment() -{ - QTextBlock block = yyProgram.lastBlock().previous(); - QString blockText; - - for (; block.isValid(); block = block.previous()) { - blockText = block.text(); - - if (! isOnlyWhiteSpace(blockText)) - break; - } - - return indentOfLine(blockText); -} - -/* - A function called match...() modifies the linizer state. If it - returns true, yyLine is the top line of the matched construct; - otherwise, the linizer is left in an unknown state. - - A function called is...() keeps the linizer state intact. -*/ - -/* - Returns true if the current line (and upwards) forms a braceless - control statement; otherwise returns false. - - The first line of the following example is a "braceless control - statement": - - if (x) - y; -*/ -bool QScriptIndenter::matchBracelessControlStatement() -{ - int delimDepth = 0; - - if (yyLine->endsWith(QLatin1String("else"))) - return true; - - if (!yyLine->endsWith(QLatin1String(")"))) - return false; - - for (int i = 0; i < SmallRoof; i++) { - int j = yyLine->length(); - while (j > 0) { - j--; - QChar ch = yyLine->at(j); - - switch (ch.unicode()) { - case ')': - delimDepth++; - break; - case '(': - delimDepth--; - if (delimDepth == 0) { - if (yyLine->indexOf(iflikeKeyword) != -1) { - /* - We have - - if (x) - y - - "if (x)" is not part of the statement - "y". - */ - return true; - } - } - if (delimDepth == -1) { - /* - We have - - if ((1 + - 2) - - and not - - if (1 + - 2) - */ - return false; - } - break; - case '{': - case '}': - case ';': - /* - We met a statement separator, but not where we - expected it. What follows is probably a weird - continuation line. Be careful with ';' in for, - though. - */ - if (ch != QLatin1Char(';') || delimDepth == 0) - return false; - } - } - - if (!readLine()) - break; - } - return false; -} - -/* - Returns true if yyLine is an unfinished line; otherwise returns - false. - - In many places we'll use the terms "standalone line", "unfinished - line" and "continuation line". The meaning of these should be - evident from this code example: - - a = b; // standalone line - c = d + // unfinished line - e + // unfinished continuation line - f + // unfinished continuation line - g; // continuation line -*/ -bool QScriptIndenter::isUnfinishedLine() -{ - bool unf = false; - - YY_SAVE(); - - if (yyLine->isEmpty()) - return false; - - QChar lastCh = yyLine->at(yyLine->length() - 1); - if (QString::fromLatin1("{};").indexOf(lastCh) == -1) { - /* - It doesn't end with ';' or similar. If it's not an "if (x)", it must be an unfinished line. - */ - unf = ! matchBracelessControlStatement(); - - if (unf && lastCh == QLatin1Char(')')) - unf = false; - - } else if (lastCh == QLatin1Char(';')) { - if (lastParen(*yyLine) == QLatin1Char('(')) { - /* - Exception: - - for (int i = 1; i < 10; - */ - unf = true; - } else if (readLine() && yyLine->endsWith(QLatin1String(";")) && - lastParen(*yyLine) == QLatin1Char('(')) { - /* - Exception: - - for (int i = 1; - i < 10; - */ - unf = true; - } - } - - YY_RESTORE(); - return unf; -} - -/* - Returns true if yyLine is a continuation line; otherwise returns - false. -*/ -bool QScriptIndenter::isContinuationLine() -{ - bool cont = false; - - YY_SAVE(); - if (readLine()) - cont = isUnfinishedLine(); - YY_RESTORE(); - return cont; -} - -/* - Returns the recommended indent for the bottom line of yyProgram, - assuming it's a continuation line. - - We're trying to align the continuation line against some parenthesis - or other bracked left opened on a previous line, or some interesting - operator such as '='. -*/ -int QScriptIndenter::indentForContinuationLine() -{ - int braceDepth = 0; - int delimDepth = 0; - - bool leftBraceFollowed = *yyLeftBraceFollows; - - for (int i = 0; i < SmallRoof; i++) { - int hook = -1; - - int j = yyLine->length(); - while (j > 0 && hook < 0) { - j--; - QChar ch = yyLine->at(j); - - switch (ch.unicode()) { - case ')': - delimDepth++; - break; - case ']': - braceDepth++; - break; - case '}': - braceDepth++; - break; - case '(': - delimDepth--; - /* - An unclosed delimiter is a good place to align at, - at least for some styles (including Qt's). - */ - if (delimDepth == -1) - hook = j; - break; - - case '[': - braceDepth--; - /* - An unclosed delimiter is a good place to align at, - at least for some styles (including Qt's). - */ - if (braceDepth == -1) - hook = j; - break; - case '{': - braceDepth--; - /* - A left brace followed by other stuff on the same - line is typically for an enum or an initializer. - Such a brace must be treated just like the other - delimiters. - */ - if (braceDepth == -1) { - if (j < yyLine->length() - 1) { - hook = j; - } else { - return 0; // shouldn't happen - } - } - break; - case '=': - /* - An equal sign is a very natural alignment hook - because it's usually the operator with the lowest - precedence in statements it appears in. Case in - point: - - int x = 1 + - 2; - - However, we have to beware of constructs such as - default arguments and explicit enum constant - values: - - void foo(int x = 0, - int y = 0); - - And not - - void foo(int x = 0, - int y = 0); - - These constructs are caracterized by a ',' at the - end of the unfinished lines or by unbalanced - parentheses. - */ - Q_ASSERT(j - 1 >= 0); - - if (QString::fromLatin1("!=<>").indexOf(yyLine->at(j - 1)) == -1 && - j + 1 < yyLine->length() && yyLine->at(j + 1) != '=') { - if (braceDepth == 0 && delimDepth == 0 && - j < yyLine->length() - 1 && - !yyLine->endsWith(QLatin1String(",")) && - (yyLine->contains('(') == yyLine->contains(')'))) - hook = j; - } - } - } - - if (hook >= 0) { - /* - Yes, we have a delimiter or an operator to align - against! We don't really align against it, but rather - against the following token, if any. In this example, - the following token is "11": - - int x = (11 + - 2); - - If there is no such token, we use a continuation indent: - - static QRegExp foo(QString( - "foo foo foo foo foo foo foo foo foo")); - */ - hook++; - while (hook < yyLine->length()) { - if (!yyLine->at(hook).isSpace()) - return columnForIndex(*yyLine, hook); - hook++; - } - return indentOfLine(*yyLine) + ppContinuationIndentSize; - } - - if (braceDepth != 0) - break; - - /* - The line's delimiters are balanced. It looks like a - continuation line or something. - */ - if (delimDepth == 0) { - if (leftBraceFollowed) { - /* - We have - - int main() - { - - or - - Bar::Bar() - : Foo(x) - { - - The "{" should be flush left. - */ - if (!isContinuationLine()) - return indentOfLine(*yyLine); - } else if (isContinuationLine() || yyLine->endsWith(QLatin1String(","))) { - /* - We have - - x = a + - b + - c; - - or - - int t[] = { - 1, 2, 3, - 4, 5, 6 - - The "c;" should fall right under the "b +", and the - "4, 5, 6" right under the "1, 2, 3,". - */ - return indentOfLine(*yyLine); - } else { - /* - We have - - stream << 1 + - 2; - - We could, but we don't, try to analyze which - operator has precedence over which and so on, to - obtain the excellent result - - stream << 1 + - 2; - - We do have a special trick above for the assignment - operator above, though. - */ - return indentOfLine(*yyLine) + ppContinuationIndentSize; - } - } - - if (!readLine()) - break; - } - return 0; -} - -/* - Returns the recommended indent for the bottom line of yyProgram if - that line is standalone (or should be indented likewise). - - Indenting a standalone line is tricky, mostly because of braceless - control statements. Grossly, we are looking backwards for a special - line, a "hook line", that we can use as a starting point to indent, - and then modify the indentation level according to the braces met - along the way to that hook. - - Let's consider a few examples. In all cases, we want to indent the - bottom line. - - Example 1: - - x = 1; - y = 2; - - The hook line is "x = 1;". We met 0 opening braces and 0 closing - braces. Therefore, "y = 2;" inherits the indent of "x = 1;". - - Example 2: - - if (x) { - y; - - The hook line is "if (x) {". No matter what precedes it, "y;" has - to be indented one level deeper than the hook line, since we met one - opening brace along the way. - - Example 3: - - if (a) - while (b) { - c; - } - d; - - To indent "d;" correctly, we have to go as far as the "if (a)". - Compare with - - if (a) { - while (b) { - c; - } - d; - - Still, we're striving to go back as little as possible to - accommodate people with irregular indentation schemes. A hook line - near at hand is much more reliable than a remote one. -*/ -int QScriptIndenter::indentForStandaloneLine() -{ - for (int i = 0; i < SmallRoof; i++) { - if (!*yyLeftBraceFollows) { - YY_SAVE(); - - if (matchBracelessControlStatement()) { - /* - The situation is this, and we want to indent "z;": - - if (x && - y) - z; - - yyLine is "if (x &&". - */ - return indentOfLine(*yyLine) + ppIndentSize; - } - YY_RESTORE(); - } - - if (yyLine->endsWith(QLatin1Char(';')) || yyLine->contains(QLatin1Char('{'))) { - /* - The situation is possibly this, and we want to indent - "z;": - - while (x) - y; - z; - - We return the indent of "while (x)". In place of "y;", - any arbitrarily complex compound statement can appear. - */ - - if (*yyBraceDepth > 0) { - do { - if (!readLine()) - break; - } while (*yyBraceDepth > 0); - } - - LinizerState hookState; - - while (isContinuationLine()) - readLine(); - hookState = yyLinizerState; - - readLine(); - if (*yyBraceDepth <= 0) { - do { - if (!matchBracelessControlStatement()) - break; - hookState = yyLinizerState; - } while (readLine()); - } - - yyLinizerState = hookState; - - while (isContinuationLine()) - readLine(); - - /* - Never trust lines containing only '{' or '}', as some - people (Richard M. Stallman) format them weirdly. - */ - if (yyLine->trimmed().length() > 1) - return indentOfLine(*yyLine) - *yyBraceDepth * ppIndentSize; - } - - if (!readLine()) - return -*yyBraceDepth * ppIndentSize; - } - return 0; -} - -/* - Returns the recommended indent for the bottom line of program. - Unless null, typedIn stores the character of yyProgram that - triggered reindentation. - - This function works better if typedIn is set properly; it is - slightly more conservative if typedIn is completely wild, and - slighly more liberal if typedIn is always null. The user might be - annoyed by the liberal behavior. -*/ -int QScriptIndenter::indentForBottomLine(QTextBlock begin, QTextBlock end, QChar typedIn) -{ - if (begin == end) - return 0; - - yyProgram = Program(begin, end); - startLinizer(); - - const QTextBlock last = end.previous(); - - QString bottomLine = last.text(); - QChar firstCh = firstNonWhiteSpace(bottomLine); - int indent = 0; - - if (bottomLineStartsInMultilineComment()) { - /* - The bottom line starts in a C-style comment. Indent it - smartly, unless the user has already played around with it, - in which case it's better to leave her stuff alone. - */ - if (isOnlyWhiteSpace(bottomLine)) { - indent = indentWhenBottomLineStartsInMultiLineComment(); - } else { - indent = indentOfLine(bottomLine); - } - } else if (okay(typedIn, QLatin1Char('#')) && firstCh == QLatin1Char('#')) { - /* - Preprocessor directives go flush left. - */ - indent = 0; - } else { - if (isUnfinishedLine()) { - indent = indentForContinuationLine(); - } else { - indent = indentForStandaloneLine(); - } - - if (okay(typedIn, QLatin1Char('}')) && firstCh == QLatin1Char('}')) { - /* - A closing brace is one level more to the left than the - code it follows. - */ - indent -= ppIndentSize; - } else if (okay(typedIn, QLatin1Char(':'))) { - QRegExp caseLabel( - QLatin1String("\\s*(?:case\\b(?:[^:]|::)+" - "|(?:default)\\s*" - ")?:.*")); - - if (caseLabel.exactMatch(bottomLine)) { - /* - Move a case label (or the ':' in front of a - constructor initialization list) one level to the - left, but only if the user did not play around with - it yet. Some users have exotic tastes in the - matter, and most users probably are not patient - enough to wait for the final ':' to format their - code properly. - - We don't attempt the same for goto labels, as the - user is probably the middle of "foo::bar". (Who - uses goto, anyway?) - */ - if (indentOfLine(bottomLine) <= indent) - indent -= ppIndentSize; - else - indent = indentOfLine(bottomLine); - } - } - } - - return qMax(0, indent); -} diff --git a/src/shared/qscripthighlighter/qscriptindenter.h b/src/shared/qscripthighlighter/qscriptindenter.h deleted file mode 100644 index 6bb0296c5a..0000000000 --- a/src/shared/qscripthighlighter/qscriptindenter.h +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#ifndef QTSCRIPTINDENTER_H -#define QTSCRIPTINDENTER_H - -#include <qscripthighlighter/qscriptincrementalscanner.h> -#include <QtCore/QRegExp> -#include <QtCore/QStringList> -#include <QtGui/QTextBlock> - -namespace SharedTools { - -class QScriptIndenter -{ - Q_DISABLE_COPY(QScriptIndenter) - -public: - QScriptIndenter(); - ~QScriptIndenter(); - - void setTabSize(int size); - void setIndentSize(int size); - - int indentForBottomLine(QTextBlock firstBlock, QTextBlock lastBlock, QChar typedIn); - QChar firstNonWhiteSpace(const QString &t) const; - -private: - static const int SmallRoof; - static const int BigRoof; - - bool isOnlyWhiteSpace(const QString &t) const; - int columnForIndex(const QString &t, int index) const; - int indentOfLine(const QString &t) const; - QString trimmedCodeLine(const QString &t); - - void eraseChar(QString &t, int k, QChar ch) const; - QChar lastParen(const QString &t) const; - bool okay(QChar typedIn, QChar okayCh) const; - - /* - The "linizer" is a group of functions and variables to iterate - through the source code of the program to indent. The program is - given as a list of strings, with the bottom line being the line - to indent. The actual program might contain extra lines, but - those are uninteresting and not passed over to us. - */ - - bool readLine(); - void startLinizer(); - bool bottomLineStartsInMultilineComment(); - int indentWhenBottomLineStartsInMultiLineComment(); - bool matchBracelessControlStatement(); - bool isUnfinishedLine(); - bool isContinuationLine(); - int indentForContinuationLine(); - int indentForStandaloneLine(); - -private: - int ppHardwareTabSize; - int ppIndentSize; - int ppContinuationIndentSize; - int ppCommentOffset; - -private: - struct LinizerState - { - LinizerState() - : braceDepth(0), - leftBraceFollows(false), - pendingRightBrace(false) - { } - - int braceDepth; - bool leftBraceFollows; - bool pendingRightBrace; - QString line; - QList<QScriptIncrementalScanner::Token> tokens; - QTextBlock iter; - }; - - class Program - { - public: - Program() {} - Program(QTextBlock begin, QTextBlock end) - : begin(begin), end(end) {} - - QTextBlock firstBlock() const { return begin; } - QTextBlock lastBlock() const { return end; } - - private: - QTextBlock begin, end; - }; - - Program yyProgram; - LinizerState yyLinizerState; - - // shorthands - const QString *yyLine; - const int *yyBraceDepth; - const bool *yyLeftBraceFollows; - - QRegExp label; - QRegExp braceX; - QRegExp iflikeKeyword; -}; - -} // namespace SharedTools - -#endif // QTSCRIPTINDENTER_H - diff --git a/src/shared/qscripthighlighter/test/main.cpp b/src/shared/qscripthighlighter/test/main.cpp deleted file mode 100644 index 5f955e3243..0000000000 --- a/src/shared/qscripthighlighter/test/main.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - -#include "qscripthighlighter.h" - -#include <QTextEdit> -#include <QMainWindow> -#include <QApplication> - -QString presetText = "import Qt 4.6\n" - "\n" - "Item {\n" - " id: Zoo\n" - " width: 1 + -1*3\n" - "}\n"; - -int main(int argc, char *argv[]) -{ - QApplication app(argc, argv); - QMainWindow mw; - - QTextEdit *textEdit = new QTextEdit; - if (!presetText.isEmpty()) - textEdit->setText(presetText); - new SharedTools::QScriptHighlighter(true, textEdit->document()); - mw.setCentralWidget(textEdit); - mw.show(); - return app.exec(); -} diff --git a/src/shared/qscripthighlighter/test/test.pro b/src/shared/qscripthighlighter/test/test.pro deleted file mode 100644 index 4962411032..0000000000 --- a/src/shared/qscripthighlighter/test/test.pro +++ /dev/null @@ -1,10 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Mon Apr 16 13:02:01 2007 -###################################################################### - -TEMPLATE = app - -QT += gui - -include(../qscripthighlighter.pri) -SOURCES += main.cpp |