Commit b0e49ecc authored by Friedemann Kleint's avatar Friedemann Kleint
Browse files

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

parents 85ef2954 f82e76dd
......@@ -28,66 +28,66 @@
**************************************************************************/
#include "duidocument.h"
#include "parser/javascriptast_p.h"
#include "parser/javascriptlexer_p.h"
#include "parser/javascriptparser_p.h"
#include "parser/javascriptengine_p.h"
#include "parser/javascriptnodepool_p.h"
#include "javascriptast_p.h"
#include "javascriptlexer_p.h"
#include "javascriptparser_p.h"
#include "javascriptengine_p.h"
#include "javascriptnodepool_p.h"
using namespace DuiEditor;
using namespace DuiEditor::Internal;
using namespace JavaScript;
DuiDocument::DuiDocument(const QString &fileName)
: _engine(0), _pool(0), _program(0), _fileName(fileName)
: _engine(0), _pool(0), _program(0), _fileName(fileName)
{
}
DuiDocument::~DuiDocument()
{
delete _engine;
delete _pool;
delete _engine;
delete _pool;
}
DuiDocument::Ptr DuiDocument::create(const QString &fileName)
{
DuiDocument::Ptr doc(new DuiDocument(fileName));
return doc;
DuiDocument::Ptr doc(new DuiDocument(fileName));
return doc;
}
AST::UiProgram *DuiDocument::program() const
{
return _program;
return _program;
}
QList<DiagnosticMessage> DuiDocument::diagnosticMessages() const
{
return _diagnosticMessages;
return _diagnosticMessages;
}
void DuiDocument::setSource(const QString &source)
{
_source = source;
_source = source;
}
bool DuiDocument::parse()
{
Q_ASSERT(! _engine);
Q_ASSERT(! _pool);
Q_ASSERT(! _program);
Q_ASSERT(! _engine);
Q_ASSERT(! _pool);
Q_ASSERT(! _program);
_engine = new Engine();
_pool = new NodePool(_fileName, _engine);
_engine = new Engine();
_pool = new NodePool(_fileName, _engine);
Lexer lexer(_engine);
Parser parser(_engine);
Lexer lexer(_engine);
Parser parser(_engine);
lexer.setCode(_source, /*line = */ 1);
lexer.setCode(_source, /*line = */ 1);
bool parsed = parser.parse();
_program = parser.ast();
_diagnosticMessages = parser.diagnosticMessages();
return parsed;
bool parsed = parser.parse();
_program = parser.ast();
_diagnosticMessages = parser.diagnosticMessages();
return parsed;
}
Snapshot::Snapshot()
......
......@@ -33,8 +33,8 @@
#include <QtCore/QMap>
#include <QtCore/QString>
#include "parser/javascriptengine_p.h"
#include "parser/javascriptastfwd_p.h"
#include "javascriptengine_p.h"
#include "javascriptastfwd_p.h"
namespace DuiEditor {
namespace Internal {
......@@ -42,36 +42,36 @@ namespace Internal {
class DuiDocument
{
public:
typedef QSharedPointer<DuiDocument> Ptr;
typedef QSharedPointer<DuiDocument> Ptr;
protected:
DuiDocument(const QString &fileName);
DuiDocument(const QString &fileName);
public:
~DuiDocument();
~DuiDocument();
static DuiDocument::Ptr create(const QString &fileName);
static DuiDocument::Ptr create(const QString &fileName);
JavaScript::AST::UiProgram *program() const;
QList<JavaScript::DiagnosticMessage> diagnosticMessages() const;
JavaScript::AST::UiProgram *program() const;
QList<JavaScript::DiagnosticMessage> diagnosticMessages() const;
void setSource(const QString &source);
bool parse();
void setSource(const QString &source);
bool parse();
private:
JavaScript::Engine *_engine;
JavaScript::NodePool *_pool;
JavaScript::AST::UiProgram *_program;
QList<JavaScript::DiagnosticMessage> _diagnosticMessages;
QString _fileName;
QString _source;
JavaScript::Engine *_engine;
JavaScript::NodePool *_pool;
JavaScript::AST::UiProgram *_program;
QList<JavaScript::DiagnosticMessage> _diagnosticMessages;
QString _fileName;
QString _source;
};
class Snapshot: public QMap<QString, DuiDocument>
{
public:
Snapshot();
~Snapshot();
Snapshot();
~Snapshot();
};
} // end of namespace Internal
......
This diff is collapsed.
......@@ -32,9 +32,8 @@
#include <texteditor/basetexteditor.h>
#include "parser/javascriptastfwd_p.h"
#include "parser/javascriptengine_p.h"
#include "javascriptastfwd_p.h"
#include "javascriptengine_p.h"
#include "duidocument.h"
QT_BEGIN_NAMESPACE
......@@ -43,7 +42,7 @@ class QTimer;
QT_END_NAMESPACE
namespace Core {
class ICore;
class ICore;
}
namespace DuiEditor {
......@@ -55,92 +54,92 @@ class ScriptEditor;
class ScriptEditorEditable : public TextEditor::BaseTextEditorEditable
{
Q_OBJECT
Q_OBJECT
public:
ScriptEditorEditable(ScriptEditor *, const QList<int> &);
QList<int> context() const;
ScriptEditorEditable(ScriptEditor *, const QList<int> &);
QList<int> context() const;
bool duplicateSupported() const { return true; }
Core::IEditor *duplicate(QWidget *parent);
const char *kind() const;
bool temporaryEditor() const { return false; }
bool duplicateSupported() const { return true; }
Core::IEditor *duplicate(QWidget *parent);
const char *kind() const;
bool temporaryEditor() const { return false; }
private:
QList<int> m_context;
QList<int> m_context;
};
struct Declaration
{
QString text;
int startLine;
int startColumn;
int endLine;
int endColumn;
Declaration()
: startLine(0),
startColumn(0),
endLine(0),
endColumn(0)
{ }
QString text;
int startLine;
int startColumn;
int endLine;
int endColumn;
Declaration()
: startLine(0),
startColumn(0),
endLine(0),
endColumn(0)
{ }
};
class ScriptEditor : public TextEditor::BaseTextEditor
{
Q_OBJECT
Q_OBJECT
public:
typedef QList<int> Context;
typedef QList<int> Context;
ScriptEditor(const Context &context,
QWidget *parent = 0);
~ScriptEditor();
ScriptEditor(const Context &context,
QWidget *parent = 0);
~ScriptEditor();
QList<Declaration> declarations() const;
QStringList words() const;
QStringList keywords() const;
QList<Declaration> declarations() const;
QStringList words() const;
QStringList keywords() const;
QList<JavaScript::DiagnosticMessage> diagnosticMessages() const
{ return m_diagnosticMessages; }
QList<JavaScript::DiagnosticMessage> diagnosticMessages() const
{ return m_diagnosticMessages; }
virtual void unCommentSelection();
virtual void unCommentSelection();
public slots:
virtual void setFontSettings(const TextEditor::FontSettings &);
virtual void setFontSettings(const TextEditor::FontSettings &);
private slots:
void updateDocument();
void updateDocumentNow();
void jumpToMethod(int index);
void updateMethodBoxIndex();
void updateMethodBoxToolTip();
void updateFileName();
void updateDocument();
void updateDocumentNow();
void jumpToMethod(int index);
void updateMethodBoxIndex();
void updateMethodBoxToolTip();
void updateFileName();
// refactoring ops
void renameIdUnderCursor();
// refactoring ops
void renameIdUnderCursor();
protected:
void contextMenuEvent(QContextMenuEvent *e);
TextEditor::BaseTextEditorEditable *createEditableInterface();
void createToolBar(ScriptEditorEditable *editable);
void contextMenuEvent(QContextMenuEvent *e);
TextEditor::BaseTextEditorEditable *createEditableInterface();
void createToolBar(ScriptEditorEditable *editable);
private:
virtual bool isElectricCharacter(const QChar &ch) const;
virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);
virtual bool isElectricCharacter(const QChar &ch) const;
virtual void indentBlock(QTextDocument *doc, QTextBlock block, QChar typedChar);
QString wordUnderCursor() const;
QString wordUnderCursor() const;
const Context m_context;
const Context m_context;
QTimer *m_updateDocumentTimer;
QComboBox *m_methodCombo;
QList<Declaration> m_declarations;
QStringList m_words;
QMap<QString, QList<JavaScript::AST::SourceLocation> > m_ids; // ### use QMultiMap
QList<JavaScript::DiagnosticMessage> m_diagnosticMessages;
DuiDocument::Ptr m_document;
QTimer *m_updateDocumentTimer;
QComboBox *m_methodCombo;
QList<Declaration> m_declarations;
QStringList m_words;
QMap<QString, QList<JavaScript::AST::SourceLocation> > m_ids; // ### use QMultiMap
QList<JavaScript::DiagnosticMessage> m_diagnosticMessages;
DuiDocument::Ptr m_document;
};
} // namespace Internal
......
TEMPLATE = lib
TARGET = DuiEditor
QT += script
include(../../qtcreatorplugin.pri)
include(../../plugins/coreplugin/coreplugin.pri)
......@@ -12,14 +11,12 @@ DUI=$$(QTDIR_DUI)
isEmpty(DUI):DUI=$$fromfile($$(QTDIR)/.qmake.cache,QT_SOURCE_TREE)
!isEmpty(DUI):exists($$DUI/src/declarative/qml/parser) {
include($$DUI/src/declarative/qml/parser/parser.pri)
INCLUDEPATH += $$DUI/src/declarative/qml
include($$DUI/src/declarative/qml/parser/parser.pri)
include($$DUI/src/declarative/qml/rewriter/rewriter.pri)
} else {
error(run with export QTDIR_DUI=<path to kinetic/qt>)
error(run with export QTDIR_DUI=<path to kinetic/qt>)
}
include(rewriter/rewriter.pri)
HEADERS += duieditor.h \
duieditorfactory.h \
duieditorplugin.h \
......
#include "rewriter.h"
#include "parser/javascriptast_p.h"
using namespace JavaScript;
using namespace DuiEditor::Internal;
void Rewriter::replace(const AST::SourceLocation &loc, const QString &text)
{ replace(loc.offset, loc.length, text); }
void Rewriter::remove(const AST::SourceLocation &loc)
{ return replace(loc.offset, loc.length, QString()); }
void Rewriter::remove(const AST::SourceLocation &firstLoc, const AST::SourceLocation &lastLoc)
{ return replace(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset, QString()); }
void Rewriter::insertTextBefore(const AST::SourceLocation &loc, const QString &text)
{ replace(loc.offset, 0, text); }
void Rewriter::insertTextAfter(const AST::SourceLocation &loc, const QString &text)
{ replace(loc.offset + loc.length, 0, text); }
void Rewriter::replace(int offset, int length, const QString &text)
{ textWriter.replace(offset, length, text); }
void Rewriter::insertText(int offset, const QString &text)
{ replace(offset, 0, text); }
void Rewriter::removeText(int offset, int length)
{ replace(offset, length, QString()); }
QString Rewriter::textAt(const AST::SourceLocation &loc) const
{ return _code.mid(loc.offset, loc.length); }
QString Rewriter::textAt(const AST::SourceLocation &firstLoc, const AST::SourceLocation &lastLoc) const
{ return _code.mid(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset); }
void Rewriter::accept(JavaScript::AST::Node *node)
{ JavaScript::AST::Node::acceptChild(node, this); }
void Rewriter::moveTextBefore(const AST::SourceLocation &firstLoc,
const AST::SourceLocation &lastLoc,
const AST::SourceLocation &loc)
{
textWriter.move(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset, loc.offset);
}
void Rewriter::moveTextAfter(const AST::SourceLocation &firstLoc,
const AST::SourceLocation &lastLoc,
const AST::SourceLocation &loc)
{
textWriter.move(firstLoc.offset, lastLoc.offset + lastLoc.length - firstLoc.offset, loc.offset + loc.length);
}
#ifndef REWRITER_H
#define REWRITER_H
#include <QList>
#include <QString>
#include "textwriter.h"
#include "parser/javascriptastvisitor_p.h"
namespace DuiEditor {
namespace Internal {
////////////////////////////////////////////////////////////////////////////////
// Replacement
////////////////////////////////////////////////////////////////////////////////
class Replacement
{
int _offset;
int _length;
QString _text;
public:
Replacement(int offset = 0, int length = 0, const QString &text = QString())
: _offset(offset), _length(length), _text(text)
{ }
bool isNull() const { return _offset == _length; }
operator bool() const { return ! isNull(); }
int offset() const { return _offset; }
int length() const { return _length; }
QString text() const { return _text; }
};
////////////////////////////////////////////////////////////////////////////////
// Rewriter
////////////////////////////////////////////////////////////////////////////////
class Rewriter: public JavaScript::AST::Visitor
{
protected:
TextWriter textWriter;
public:
//
// Token based API
//
/// Returns the text of the token at the given \a location.
QString textAt(const JavaScript::AST::SourceLocation &location) const;
QString textAt(const JavaScript::AST::SourceLocation &firstLoc,
const JavaScript::AST::SourceLocation &lastLoc) const;
/// Replace the token at \a loc with the given \a text.
void replace(const JavaScript::AST::SourceLocation &loc, const QString &text);
/// Remove the token at the given \a location.
void remove(const JavaScript::AST::SourceLocation &location);
/// Remove all tokens in the range [\a firstLoc, \a lastLoc].
void remove(const JavaScript::AST::SourceLocation &firstLoc, const JavaScript::AST::SourceLocation &lastLoc);
/// Insert \a text before the token at the given \a location.
void insertTextBefore(const JavaScript::AST::SourceLocation &location, const QString &text);
/// Insert \a text after the token at the given \a location.
void insertTextAfter(const JavaScript::AST::SourceLocation &loc, const QString &text);
void moveTextBefore(const JavaScript::AST::SourceLocation &firstLoc,
const JavaScript::AST::SourceLocation &lastLoc,
const JavaScript::AST::SourceLocation &loc);
void moveTextAfter(const JavaScript::AST::SourceLocation &firstLoc,
const JavaScript::AST::SourceLocation &lastLoc,
const JavaScript::AST::SourceLocation &loc);
//
// low-level offset based API
//
void replace(int offset, int length, const QString &text);
void insertText(int offset, const QString &text);
void removeText(int offset, int length);
/// Visit the given \a node.
void accept(JavaScript::AST::Node *node);
/// Returns the original unchanged source code.
QString code() const { return _code; }
/// Returns the list of replacements.
QList<Replacement> replacementList() const { return _replacementList; }
protected:
/// \internal
void setCode(const QString &code) { _code = code; }
private:
QString _code;
QList<Replacement> _replacementList;
};
} // end of namespace Internal
} // end of namespace DuiEditor
#endif // REWRITER_H
HEADERS += $$PWD/rewriter.h $$PWD/textwriter.h
SOURCES += $$PWD/rewriter.cpp $$PWD/textwriter.cpp
#include "textwriter.h"
using namespace DuiEditor::Internal;
TextWriter::TextWriter()
:string(0), cursor(0)
{
}
static bool overlaps(int posA, int lengthA, int posB, int lengthB) {
return (posA < posB + lengthB && posA + lengthA > posB + lengthB)
|| (posA < posB && posA + lengthA > posB);
}
bool TextWriter::hasOverlap(int pos, int length)
{
{
QListIterator<Replace> i(replaceList);
while (i.hasNext()) {
const Replace &cmd = i.next();
if (overlaps(pos, length, cmd.pos, cmd.length))
return true;
}
}
{
QListIterator<Move> i(moveList);
while (i.hasNext()) {
const Move &cmd = i.next();
if (overlaps(pos, length, cmd.pos, cmd.length))
return true;
}
return false;
}
}
bool TextWriter::hasMoveInto(int pos, int length)
{
QListIterator<Move> i(moveList);
while (i.hasNext()) {
const Move &cmd = i.next();
if (cmd.to >= pos && cmd.to < pos + length)
return true;
}
return false;
}
void TextWriter::replace(int pos, int length, const QString &replacement)
{
Q_ASSERT(!hasOverlap(pos, length));
Q_ASSERT(!hasMoveInto(pos, length));
Replace cmd;
cmd.pos = pos;
cmd.length = length;
cmd.replacement = replacement;
replaceList += cmd;
}
void TextWriter::move(int pos, int length, int to)
{
Q_ASSERT(!hasOverlap(pos, length));
Move cmd;
cmd.pos = pos;
cmd.length = length;
cmd.to = to;
moveList += cmd;
}
void TextWriter::doReplace(const Replace &replace)
{
int diff = replace.replacement.size() - replace.length;
{
QMutableListIterator<Replace> i(replaceList);
while (i.hasNext()) {
Replace &c = i.next();
if (replace.pos < c.pos)
c.pos += diff;
else if (replace.pos + replace.length < c.pos + c.length)
c.length += diff;
}
}
{