QuickFix: Move helpers from QuickFixData to RefactoringFile.

Makes them easy to use everywhere. Also when calling
QuickFixData::textOf and friends, it wasn't really clear which file
they would run on.
This commit is contained in:
Christian Kamm
2010-08-13 12:49:11 +02:00
parent bbe64796a0
commit 7a5df3c39d
14 changed files with 212 additions and 318 deletions

View File

@@ -92,22 +92,22 @@ public:
"Move Component into '%1.qml'").arg(m_componentName));
}
virtual void performChanges(TextEditor::RefactoringFile *currentFile, QmlJSRefactoringChanges *refactoring)
virtual void performChanges(QmlJSRefactoringFile *currentFile, QmlJSRefactoringChanges *refactoring)
{
const QString newFileName = QFileInfo(fileName()).path()
+ QDir::separator() + m_componentName + QLatin1String(".qml");
QString imports;
UiProgram *prog = state().semanticInfo().document->qmlProgram();
UiProgram *prog = currentFile->qmljsDocument()->qmlProgram();
if (prog && prog->imports) {
const int start = startPosition(prog->imports->firstSourceLocation());
const int end = startPosition(prog->members->member->firstSourceLocation());
imports = state().textOf(start, end);
const int start = currentFile->startOf(prog->imports->firstSourceLocation());
const int end = currentFile->startOf(prog->members->member->firstSourceLocation());
imports = currentFile->textOf(start, end);
}
const int start = startPosition(m_objDef->firstSourceLocation());
const int end = startPosition(m_objDef->lastSourceLocation());
const QString txt = imports + state().textOf(start, end)
const int start = currentFile->startOf(m_objDef->firstSourceLocation());
const int end = currentFile->startOf(m_objDef->lastSourceLocation());
const QString txt = imports + currentFile->textOf(start, end)
+ QLatin1String("}\n");
// stop if we can't create the new file
@@ -117,7 +117,7 @@ public:
Utils::ChangeSet changes;
changes.replace(start, end, m_componentName + QLatin1String(" {\n"));
currentFile->change(changes);
currentFile->indent(range(start, end + 1));
currentFile->indent(Range(start, end + 1));
}
};
@@ -126,7 +126,7 @@ public:
QList<QmlJSQuickFixOperation::Ptr> ComponentFromObjectDef::match(const QmlJSQuickFixState &state)
{
QList<QmlJSQuickFixOperation::Ptr> result;
const int pos = state.textCursor().position();
const int pos = state.currentFile().cursor().position();
QList<Node *> path = state.semanticInfo().astPath(pos);
for (int i = path.size() - 1; i >= 0; --i) {

View File

@@ -67,9 +67,9 @@ Document::Ptr QmlJSQuickFixState::document() const
return _semanticInfo.document;
}
unsigned QmlJSQuickFixState::startPosition(const QmlJS::AST::SourceLocation &loc) const
const QmlJSRefactoringFile QmlJSQuickFixState::currentFile() const
{
return position(loc.startLine, loc.startColumn);
return QmlJSRefactoringFile(editor(), document());
}
QmlJSQuickFixOperation::QmlJSQuickFixOperation(const QmlJSQuickFixState &state, int priority)
@@ -86,7 +86,7 @@ void QmlJSQuickFixOperation::perform()
{
QmlJSRefactoringChanges refactoring(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>(),
_state.snapshot());
TextEditor::RefactoringFile current = refactoring.file(fileName());
QmlJSRefactoringFile current = refactoring.file(fileName());
performChanges(&current, &refactoring);
}

View File

@@ -64,7 +64,6 @@ class QmlJSQuickFixState: public TextEditor::QuickFixState
public:
/// Creates a new state for the given editor.
QmlJSQuickFixState(TextEditor::BaseTextEditor *editor);
typedef Utils::ChangeSet::Range Range;
Internal::SemanticInfo semanticInfo() const;
@@ -74,11 +73,7 @@ public:
/// \returns the document of the editor
QmlJS::Document::Ptr document() const;
/*!
\returns the offset in the document for the start position of the given
source location.
*/
unsigned startPosition(const QmlJS::AST::SourceLocation &loc) const;
const QmlJSRefactoringFile currentFile() const;
private:
Internal::SemanticInfo _semanticInfo;
@@ -108,7 +103,9 @@ public:
virtual void perform();
protected:
virtual void performChanges(TextEditor::RefactoringFile *currentFile, QmlJSRefactoringChanges *refactoring) = 0;
typedef Utils::ChangeSet::Range Range;
virtual void performChanges(QmlJSRefactoringFile *currentFile, QmlJSRefactoringChanges *refactoring) = 0;
/// \returns A const-reference to the state of the operation.
const QmlJSQuickFixState &state() const;
@@ -116,15 +113,6 @@ protected:
/// \returns The name of the file for for which this operation is invoked.
QString fileName() const;
protected: // Utility functions forwarding to QmlJSQuickFixState
/// \see QmlJSQuickFixState#startPosition
unsigned startPosition(const QmlJS::AST::SourceLocation &loc) const
{ return state().startPosition(loc); }
/// \see QmlJSQuickFixState#range
static QmlJSQuickFixState::Range range(int start, int end)
{ return QmlJSQuickFixState::range(start, end); }
private:
QmlJSQuickFixState _state;
};

View File

@@ -56,7 +56,7 @@ public:
UiObjectInitializer *objectInitializer = 0;
const int pos = state.textCursor().position();
const int pos = state.currentFile().cursor().position();
if (QmlJS::AST::Node *member = state.semanticInfo().declaringMember(pos)) {
if (QmlJS::AST::UiObjectBinding *b = QmlJS::AST::cast<QmlJS::AST::UiObjectBinding *>(member)) {
@@ -88,7 +88,7 @@ private:
"Split initializer"));
}
virtual void performChanges(TextEditor::RefactoringFile *currentFile, QmlJSRefactoringChanges *)
virtual void performChanges(QmlJSRefactoringFile *currentFile, QmlJSRefactoringChanges *)
{
Q_ASSERT(_objectInitializer != 0);
@@ -99,17 +99,17 @@ private:
const QmlJS::AST::SourceLocation loc = member->firstSourceLocation();
// insert a newline at the beginning of this binding
changes.insert(startPosition(loc), QLatin1String("\n"));
changes.insert(currentFile->startOf(loc), QLatin1String("\n"));
}
}
// insert a newline before the closing brace
changes.insert(startPosition(_objectInitializer->rbraceToken),
changes.insert(currentFile->startOf(_objectInitializer->rbraceToken),
QLatin1String("\n"));
currentFile->change(changes);
currentFile->indent(range(startPosition(_objectInitializer->lbraceToken),
startPosition(_objectInitializer->rbraceToken)));
currentFile->indent(Range(currentFile->startOf(_objectInitializer->lbraceToken),
currentFile->startOf(_objectInitializer->rbraceToken)));
}
};
};

View File

@@ -45,6 +45,16 @@ QmlJSRefactoringChanges::QmlJSRefactoringChanges(ModelManagerInterface *modelMan
Q_ASSERT(modelManager);
}
const Snapshot &QmlJSRefactoringChanges::snapshot() const
{
return m_snapshot;
}
QmlJSRefactoringFile QmlJSRefactoringChanges::file(const QString &fileName)
{
return QmlJSRefactoringFile(fileName, this);
}
void QmlJSRefactoringChanges::indentSelection(const QTextCursor &selection) const
{
// ### shares code with QmlJSTextEditor::indent
@@ -68,3 +78,43 @@ void QmlJSRefactoringChanges::fileChanged(const QString &fileName)
{
m_modelManager->updateSourceFiles(QStringList(fileName), true);
}
QmlJSRefactoringFile::QmlJSRefactoringFile()
{ }
QmlJSRefactoringFile::QmlJSRefactoringFile(const QString &fileName, QmlJSRefactoringChanges *refactoringChanges)
: RefactoringFile(fileName, refactoringChanges)
{ }
QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::BaseTextEditor *editor, QmlJS::Document::Ptr document)
: RefactoringFile()
, m_qmljsDocument(document)
{
m_fileName = document->fileName();
m_editor = editor;
}
Document::Ptr QmlJSRefactoringFile::qmljsDocument() const
{
if (!m_qmljsDocument) {
const QString source = document()->toPlainText();
const QString name = fileName();
const Snapshot &snapshot = refactoringChanges()->snapshot();
m_qmljsDocument = snapshot.documentFromSource(source, name);
m_qmljsDocument->parse();
}
return m_qmljsDocument;
}
unsigned QmlJSRefactoringFile::startOf(const QmlJS::AST::SourceLocation &loc) const
{
return position(loc.startLine, loc.startColumn);
}
QmlJSRefactoringChanges *QmlJSRefactoringFile::refactoringChanges() const
{
return static_cast<QmlJSRefactoringChanges *>(m_refactoringChanges);
}

View File

@@ -40,12 +40,40 @@ class ModelManagerInterface;
namespace QmlJSEditor {
class QmlJSRefactoringChanges;
class QmlJSRefactoringFile: public TextEditor::RefactoringFile
{
public:
QmlJSRefactoringFile();
QmlJSRefactoringFile(const QString &fileName, QmlJSRefactoringChanges *refactoringChanges);
QmlJSRefactoringFile(TextEditor::BaseTextEditor *editor, QmlJS::Document::Ptr document);
QmlJS::Document::Ptr qmljsDocument() const;
/*!
\returns the offset in the document for the start position of the given
source location.
*/
unsigned startOf(const QmlJS::AST::SourceLocation &loc) const;
private:
QmlJSRefactoringChanges *refactoringChanges() const;
mutable QmlJS::Document::Ptr m_qmljsDocument;
};
class QmlJSRefactoringChanges: public TextEditor::RefactoringChanges
{
public:
QmlJSRefactoringChanges(QmlJS::ModelManagerInterface *modelManager,
const QmlJS::Snapshot &snapshot);
const QmlJS::Snapshot &snapshot() const;
QmlJSRefactoringFile file(const QString &fileName);
private:
virtual void indentSelection(const QTextCursor &selection) const;
virtual void fileChanged(const QString &fileName);