Commit da5d6d7d authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Get rid of the old deprecated indenter.

parent 9df9695a
......@@ -73,8 +73,6 @@
#include <texteditor/basetextdocument.h>
#include <texteditor/fontsettings.h>
#include <texteditor/texteditorconstants.h>
#include <texteditor/textblockiterator.h>
#include <indenter.h>
#include <QtCore/QDebug>
#include <QtCore/QTime>
......
......@@ -3,7 +3,6 @@ TARGET = CppEditor
DEFINES += CPPEDITOR_LIBRARY
include(../../qtcreatorplugin.pri)
include($$IDE_SOURCE_TREE/src/libs/utils/utils.pri)
include($$IDE_SOURCE_TREE/src/shared/indenter/indenter.pri)
include($$IDE_SOURCE_TREE/src/libs/cplusplus/cplusplus.pri)
include(cppeditor_dependencies.pri)
HEADERS += cppplugin.h \
......
......@@ -9,7 +9,6 @@ include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/texteditor/texteditor.pri)
include(../../plugins/cppeditor/cppeditor.pri)
include(../../plugins/find/find.pri)
include(../../shared/indenter/indenter.pri)
# DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
QT += gui
......
......@@ -57,7 +57,6 @@
#include <texteditor/texteditorconstants.h>
#include <texteditor/tabsettings.h>
#include <texteditor/texteditorsettings.h>
#include <texteditor/textblockiterator.h>
#include <find/findplugin.h>
#include <find/textfindconstants.h>
......
......@@ -56,7 +56,6 @@
#include <extensionsystem/pluginmanager.h>
#include <texteditor/basetextdocument.h>
#include <texteditor/fontsettings.h>
#include <texteditor/textblockiterator.h>
#include <texteditor/texteditorconstants.h>
#include <texteditor/texteditorsettings.h>
#include <texteditor/syntaxhighlighter.h>
......
include(../../plugins/coreplugin/coreplugin.pri)
include(../../plugins/texteditor/texteditor.pri)
include(../../plugins/projectexplorer/projectexplorer.pri)
include(../../shared/indenter/indenter.pri)
include(../../libs/qmljs/qmljs.pri)
include(../../libs/utils/utils.pri)
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 "textblockiterator.h"
#include <QtGui/QTextDocument>
using namespace TextEditor;
TextBlockIterator::TextBlockIterator()
: m_document(0),
m_initialized(false)
{ }
TextBlockIterator::TextBlockIterator(const QTextBlock &block)
: m_document(block.document()),
m_block(block),
m_initialized(false)
{ }
bool TextBlockIterator::equals(const TextBlockIterator &other) const
{
if (m_document != other.m_document)
return false;
return m_block == other.m_block;
}
QString TextBlockIterator::operator*() const
{
if (! m_initialized)
read();
return m_text;
}
void TextBlockIterator::read() const
{
m_initialized = true;
m_text = m_block.text();
}
TextBlockIterator &TextBlockIterator::operator++()
{
m_initialized = false;
m_block = m_block.next();
return *this;
}
TextBlockIterator &TextBlockIterator::operator--()
{
m_initialized = false;
m_block = m_block.previous();
return *this;
}
TextBlockIterator TextBlockIterator::operator++(int)
{
TextBlockIterator prev;
++*this;
return prev;
}
TextBlockIterator TextBlockIterator::operator--(int)
{
TextBlockIterator prev;
--*this;
return prev;
}
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 TEXTBLOCKITERATOR_H
#define TEXTBLOCKITERATOR_H
#include "texteditor_global.h"
#include <QtGui/QTextBlock>
namespace TextEditor {
/* Iterator for the text blocks of a document. */
class TEXTEDITOR_EXPORT TextBlockIterator {
public:
TextBlockIterator();
TextBlockIterator(const QTextBlock &block);
bool equals(const TextBlockIterator &o) const;
QString operator*() const;
TextBlockIterator &operator++();
TextBlockIterator &operator--();
TextBlockIterator operator++(int);
TextBlockIterator operator--(int);
private:
void read() const;
private:
const QTextDocument *m_document;
QTextBlock m_block;
mutable QString m_text;
mutable bool m_initialized;
};
inline bool operator==(const TextBlockIterator &i1, const TextBlockIterator &i2) { return i1.equals(i2); }
inline bool operator!=(const TextBlockIterator &i1, const TextBlockIterator &i2) { return !i1.equals(i2); }
} // namespace TextEditor
#endif // TEXTBLOCKITERATOR_H
......@@ -26,7 +26,6 @@ SOURCES += texteditorplugin.cpp \
displaysettings.cpp \
displaysettingspage.cpp \
fontsettings.cpp \
textblockiterator.cpp \
linenumberfilter.cpp \
basetextmark.cpp \
findinfiles.cpp \
......@@ -90,7 +89,6 @@ HEADERS += texteditorplugin.h \
displaysettings.h \
displaysettingspage.h \
fontsettings.h \
textblockiterator.h \
itexteditable.h \
itexteditor.h \
linenumberfilter.h \
......
C++ / Qt Script indenter based on:
research/qsa/quickport/src/neweditor/yyindent.cpp
Known issues:
- Using an indentation different from 4 makes it goof up.
History:
- 070510: Split off the test application and made it work with Qt 4.
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 "indenter.h"
using namespace SharedTools::IndenterInternal;
// --- Constants
Constants::Constants() :
m_slashAster(QLatin1String("/*")),
m_asterSlash(QLatin1String("*/")),
m_slashSlash(QLatin1String("//")),
m_else(QLatin1String("else")),
m_qobject(QLatin1String("Q_OBJECT")),
m_operators(QLatin1String("!=<>")),
m_bracesSemicolon(QLatin1String("{};")),
m_3dots(QLatin1String("...")),
m_literal(QLatin1String("([\"'])(?:\\\\.|[^\\\\])*\\1")),
m_label(QLatin1String("^\\s*((?:case\\b([^:]|::)+|[a-zA-Z_0-9]+)(?:\\s+slots|\\s+Q_SLOTS)?:)(?!:)")),
m_inlineCComment(QLatin1String("/\\*.*\\*/")),
m_braceX(QLatin1String("^\\s*\\}\\s*(?:else|catch)\\b")),
m_iflikeKeyword(QLatin1String("\\b(?:catch|do|for|if|while|foreach)\\b")),
m_caseLabel(QLatin1String("^\\s*(?:case\\b(?:[^:]|::)+"
"|(?:public|protected|private|signals|Q_SIGNALS|default)(?:\\s+slots|\\s+Q_SLOTS)?\\s*"
"):")),
m_templateFunc(QLatin1String("template<.*>"))
{
m_literal.setMinimal(true);
m_inlineCComment.setMinimal(true);
Q_ASSERT(m_literal.isValid());
Q_ASSERT(m_label.isValid());
Q_ASSERT(m_inlineCComment.isValid());
Q_ASSERT(m_braceX.isValid());
Q_ASSERT(m_iflikeKeyword.isValid());
Q_ASSERT(m_caseLabel.isValid());
Q_ASSERT(m_templateFunc.isValid());
}
This diff is collapsed.
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 INDENTER_H
#define INDENTER_H
#include "texteditor/basetexteditor.h"
#include "texteditor/textblockiterator.h"
#include <QtCore/QString>
#include <QtCore/QStringList>
namespace SharedTools {
namespace IndenterInternal {
/* String constants and regexps required by the indenter. Separate for code cleanliness*/
struct Constants {
Constants();
const QString m_slashAster;
const QString m_asterSlash;
const QString m_slashSlash;
const QString m_else;
const QString m_qobject;
const QString m_operators;
const QString m_bracesSemicolon;
const QString m_3dots;
QRegExp m_literal;
QRegExp m_label;
QRegExp m_inlineCComment;
QRegExp m_braceX;
QRegExp m_iflikeKeyword;
QRegExp m_caseLabel;
QRegExp m_templateFunc;
};
/* 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. */
struct LinizerState {
QString line;
int braceDepth;
bool leftBraceFollows;
TextEditor::TextBlockIterator iter;
bool inCComment;
bool pendingRightBrace;
};
}
/* Indenter singleton as a template of a bidirectional input iterator
* of a sequence of code lines represented as QString.
* When setting the parameters, be careful to
* specify the correct template parameters (best use a typedef). */
class Indenter {
typedef TextEditor::TextBlockIterator Iterator;
Indenter(const Indenter&);
Indenter &operator=(const Indenter&);
Indenter();
public:
~Indenter();
static Indenter &instance();
void setIndentSize(int size);
void setTabSize(int size );
void setIndentBraces(bool indent);
void setDoubleIndentBlocks(bool indent);
/* Return indentation for the last line of the sequence
* based on the previous lines. */
int indentForBottomLine(const Iterator &current,
const Iterator &programBegin,
const Iterator &programEnd,
QChar typedIn);
// Helpers.
static bool isOnlyWhiteSpace( const QString& t);
static QChar firstNonWhiteSpace( const QString& t );
private:
int columnForIndex( const QString& t, int index ) const;
int indentOfLine( const QString& t ) const;
QString trimmedCodeLine( const QString& t );
bool readLine();
void startLinizer();
bool bottomLineStartsInCComment();
int indentWhenBottomLineStartsInCComment() const;
bool matchBracelessControlStatement();
bool isUnfinishedLine();
bool isContinuationLine();
int indentForContinuationLine();
int indentForStandaloneLine();
IndenterInternal::Constants m_constants;
int ppHardwareTabSize;
int ppIndentSize;
bool ppIndentBraces;
int ppContinuationIndentSize;
bool ppDoubleIndentBlocks;
Iterator yyProgramBegin;
Iterator yyProgramEnd;
typedef IndenterInternal::LinizerState LinizerState;
LinizerState *yyLinizerState ;
// shorthands
const QString *yyLine;
const int *yyBraceDepth;
const bool *yyLeftBraceFollows;
};
}
#endif // INDENTER_H
INCLUDEPATH *= $$PWD
SOURCES += $$PWD/constants.cpp $$PWD/indenter.cpp
HEADERS += $$PWD/indenter.h
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 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 "indenter.h"
#include <QtCore/QFile>
#include <QtCore/QStringList>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
#include <QtCore/QFileInfo>
#include <stdio.h>
typedef SharedTools::Indenter<QStringList::const_iterator> Indenter;
static QString fileContents(const QString &fileName)
{
QFile f(fileName);
if (!f.open(QIODevice::ReadOnly)) {
const QString msg = QString(QLatin1String("error: Cannot open file '%1' for reading: %2")).
arg(fileName).arg(f.errorString());
qWarning(msg.toLatin1().constData());
return QString::null;
}
const QString contents = QString::fromUtf8(f.readAll());
f.close();
if ( contents.isEmpty() ) {
const QString msg = QString(QLatin1String("error: File '%1' is empty")).arg(fileName);
qWarning(msg.toLatin1().constData());
return QString::null;
}
return contents;
}
static void printUsage(char *a0)
{
const QFileInfo fi(QString::fromUtf8(a0));
const QString usage = QString(QLatin1String("Usage: %1 [-i indent-size] [-t tab-size] file.cpp")).
arg(fi.fileName());
qWarning(usage.toUtf8().constData());
}
static int integerOptionArgument(char ** &aptr, char **end)
{
if (++aptr == end)
return -1;
const QString arg = QString::fromUtf8(*aptr);
bool ok;
const int rc = arg.toInt (&ok);
if (!ok)
return -1;
return rc;
}
static QStringList parseCommandLine(char **begin, char **end)
{
char **aptr = begin;
if (++aptr == end)
return QStringList();
QStringList fileNames;
for ( ; aptr != end; ++aptr) {
const char *arg = *aptr;
if (arg[0] == '-') {
switch (arg[1]) {
case 't': {
const int tabSize = integerOptionArgument(aptr, end);
if ( tabSize == -1)
return QStringList();
Indenter::instance().setTabSize(tabSize);
}
break;
case 'i': {
const int indentSize = integerOptionArgument(aptr, end);
if (indentSize == -1)
return QStringList();
Indenter::instance().setIndentSize(indentSize);
}
break;
default:
return QStringList();
}
} else {
fileNames.push_back(QString::fromUtf8(arg));
}
}
return fileNames;
}
int format(const QString &fileName)
{
const QString code = fileContents(fileName);
if (code.isEmpty())
return 1;
QStringList program = code.split(QLatin1Char('\n'), QString::KeepEmptyParts);
while (!program.isEmpty()) {
if (!program.back().trimmed().isEmpty())
break;
program.pop_back();
}
QStringList p;
QString out;
const QChar colon = QLatin1Char(':');
const QChar blank = QLatin1Char(' ');
const QChar newLine = QLatin1Char('\n');
QStringList::const_iterator cend = program.constEnd();
for (QStringList::const_iterator it = program.constBegin(); it != cend; ++it) {
p.push_back(*it);
QString &line = p.back();
QChar typedIn = Indenter::instance().firstNonWhiteSpace(line);
if (p.last().endsWith(colon))
typedIn = colon;
const int indent = Indenter::instance().indentForBottomLine(it, p.constBegin(), p.constEnd(), typedIn);
const QString trimmed = line.trimmed();