diff options
author | Christian Kamm <christian.d.kamm@nokia.com> | 2011-08-17 11:35:57 +0200 |
---|---|---|
committer | Christian Kamm <christian.d.kamm@nokia.com> | 2011-08-19 11:12:09 +0200 |
commit | 8a6d767a8f2f98ea4e04847f92cff40d661b806f (patch) | |
tree | 586e5c539adfbb18623246d00dec5e894288c8e1 /src/plugins | |
parent | a07acad516b5fa1ac503493b4ec28d595f6e1ea0 (diff) | |
download | qt-creator-8a6d767a8f2f98ea4e04847f92cff40d661b806f.tar.gz |
Refactoring changes: Cleanup and improvements.
Previously RefactoringFiles were usually passed around by value.
However, since a RefactoringFile may sometimes own a QTextDocument
(when it was read from a file), that's not great and caused the
file to be reread after every copy.
With this change RefactoringFile becomes noncopyable and is always
owned by a shared pointer.
This change also allowed having const RefactoringFiles which is
useful because they can be safely used from other threads. See
CppRefactoringChanges::fileNoEditor.
Change-Id: I9045921d6d0f6349f9558ff2a3d8317ea172193b
Reviewed-on: http://codereview.qt.nokia.com/3084
Reviewed-by: Leandro T. C. Melo <leandro.melo@nokia.com>
Diffstat (limited to 'src/plugins')
28 files changed, 585 insertions, 476 deletions
diff --git a/src/plugins/cppeditor/cppcompleteswitch.cpp b/src/plugins/cppeditor/cppcompleteswitch.cpp index 05ec2c440e..dd287f3987 100644 --- a/src/plugins/cppeditor/cppcompleteswitch.cpp +++ b/src/plugins/cppeditor/cppcompleteswitch.cpp @@ -116,15 +116,17 @@ public: } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, + const CppRefactoringChanges &) { ChangeSet changes; int start = currentFile->endOf(compoundStatement->lbrace_token); changes.insert(start, QLatin1String("\ncase ") + values.join(QLatin1String(":\nbreak;\ncase ")) + QLatin1String(":\nbreak;")); - currentFile->change(changes); - currentFile->indent(currentFile->range(compoundStatement)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(currentFile->range(compoundStatement)); + currentFile->apply(); } CompoundStatementAST *compoundStatement; diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp index 0a5a49777c..9f33c62ffd 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp @@ -42,6 +42,7 @@ #include <cplusplus/TranslationUnit.h> #include <cplusplus/LookupContext.h> #include <cplusplus/Overview.h> +#include <cpptools/cpprefactoringchanges.h> #include <texteditor/refactoroverlay.h> #include <texteditor/tooltip/tooltip.h> #include <texteditor/tooltip/tipcontents.h> @@ -76,10 +77,11 @@ QTextCursor FunctionDeclDefLinkFinder::scannedSelection() const } // parent is either a FunctionDefinitionAST or a SimpleDeclarationAST -static bool findDeclOrDef(const Document::Ptr &doc, const QTextCursor &cursor, +// line and column are 1-based +static bool findDeclOrDef(const Document::Ptr &doc, int line, int column, DeclarationAST **parent, FunctionDeclaratorAST **funcDecl) { - QList<AST *> path = ASTPath(doc)(cursor); + QList<AST *> path = ASTPath(doc)(line, column); // for function definitions, simply scan for FunctionDefinitionAST not preceded // by CompoundStatement/CtorInitializer @@ -113,19 +115,19 @@ static bool findDeclOrDef(const Document::Ptr &doc, const QTextCursor &cursor, return *funcDecl; } -static void declDefLinkStartEnd(const CppTools::CppRefactoringFile &file, +static void declDefLinkStartEnd(const CppTools::CppRefactoringFileConstPtr &file, DeclarationAST *parent, FunctionDeclaratorAST *funcDecl, int *start, int *end) { - *start = file.startOf(parent); + *start = file->startOf(parent); if (funcDecl->trailing_return_type) - *end = file.endOf(funcDecl->trailing_return_type); + *end = file->endOf(funcDecl->trailing_return_type); else if (funcDecl->exception_specification) - *end = file.endOf(funcDecl->exception_specification); + *end = file->endOf(funcDecl->exception_specification); else if (funcDecl->cv_qualifier_list) - *end = file.endOf(funcDecl->cv_qualifier_list->lastValue()); + *end = file->endOf(funcDecl->cv_qualifier_list->lastValue()); else - *end = file.endOf(funcDecl->rparen_token); + *end = file->endOf(funcDecl->rparen_token); } static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<FunctionDeclDefLink> link, CppTools::CppRefactoringChanges changes) @@ -152,15 +154,14 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio // parse the target file to get the linked decl/def const QString targetFileName = QString::fromUtf8( target->fileName(), target->fileNameLength()); - CppTools::CppRefactoringFile targetFile = changes.file(targetFileName); - if (!targetFile.isValid()) + CppTools::CppRefactoringFileConstPtr targetFile = changes.fileNoEditor(targetFileName); + if (!targetFile->isValid()) return noResult; - QTextCursor tc(targetFile.cursor()); - tc.setPosition(targetFile.position(target->line(), target->column())); DeclarationAST *targetParent = 0; FunctionDeclaratorAST *targetFuncDecl = 0; - if (!findDeclOrDef(targetFile.cppDocument(), tc, &targetParent, &targetFuncDecl)) + if (!findDeclOrDef(targetFile->cppDocument(), target->line(), target->column(), + &targetParent, &targetFuncDecl)) return noResult; // the parens are necessary for finding good places for changes @@ -169,16 +170,14 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio int targetStart, targetEnd; declDefLinkStartEnd(targetFile, targetParent, targetFuncDecl, &targetStart, &targetEnd); - QString targetInitial = targetFile.textOf( - targetFile.startOf(targetParent), + QString targetInitial = targetFile->textOf( + targetFile->startOf(targetParent), targetEnd); link->targetOffset = targetStart; link->targetInitial = targetInitial; - link->targetFile = QSharedPointer<CppTools::CppRefactoringFile>( - new CppTools::CppRefactoringFile(targetFile.document()->clone(), targetFile.fileName())); - link->targetFile->setCppDocument(targetFile.cppDocument()); + link->targetFile = targetFile; link->targetFunction = targetFuncDecl->symbol; link->targetFunctionDeclarator = targetFuncDecl; link->targetDeclaration = targetParent; @@ -192,13 +191,13 @@ void FunctionDeclDefLinkFinder::startFindLinkAt( // check if cursor is on function decl/def DeclarationAST *parent = 0; FunctionDeclaratorAST *funcDecl = 0; - if (!findDeclOrDef(doc, cursor, &parent, &funcDecl)) + if (!findDeclOrDef(doc, cursor.blockNumber() + 1, cursor.columnNumber() + 1, &parent, &funcDecl)) return; // find the start/end offsets CppTools::CppRefactoringChanges refactoringChanges(snapshot); - CppTools::CppRefactoringFile sourceFile = refactoringChanges.file(doc->fileName()); - sourceFile.setCppDocument(doc); + CppTools::CppRefactoringFilePtr sourceFile = refactoringChanges.file(doc->fileName()); + sourceFile->setCppDocument(doc); int start, end; declDefLinkStartEnd(sourceFile, parent, funcDecl, &start, &end); @@ -242,7 +241,7 @@ FunctionDeclDefLink::~FunctionDeclDefLink() bool FunctionDeclDefLink::isValid() const { - return targetFile; + return !linkSelection.isNull(); } bool FunctionDeclDefLink::isMarkerVisible() const @@ -274,18 +273,16 @@ void FunctionDeclDefLink::apply(CPPEditorWidget *editor, bool jumpToMatch) // first verify the interesting region of the target file is unchanged CppTools::CppRefactoringChanges refactoringChanges(snapshot); - CppTools::CppRefactoringFile newTargetFile = refactoringChanges.file(targetFile->fileName()); - if (!newTargetFile.isValid()) + CppTools::CppRefactoringFilePtr newTargetFile = refactoringChanges.file(targetFile->fileName()); + if (!newTargetFile->isValid()) return; const int targetEnd = targetOffset + targetInitial.size(); - if (targetInitial == newTargetFile.textOf(targetOffset, targetEnd)) { + if (targetInitial == newTargetFile->textOf(targetOffset, targetEnd)) { const Utils::ChangeSet changeset = changes(snapshot); - newTargetFile.change(changeset, jumpToMatch); - if (jumpToMatch) { - QTextCursor tc = newTargetFile.cursor(); - tc.setPosition(targetOffset + targetInitial.size()); - refactoringChanges.activateEditor(newTargetFile.fileName(), tc.blockNumber(), tc.columnNumber()); - } + newTargetFile->setChangeSet(changeset); + if (jumpToMatch) + newTargetFile->setOpenEditor(true, targetOffset); + newTargetFile->apply(); } else { TextEditor::ToolTip::instance()->show( editor->toolTipPosition(linkSelection), @@ -361,8 +358,6 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot) { Utils::ChangeSet changes; - QSharedPointer<CppTools::CppRefactoringFile> matchFile = targetFile; - // parse the current source declaration TypeOfExpression typeOfExpression; // ### just need to preprocess... typeOfExpression.init(sourceDocument, snapshot); @@ -412,15 +407,15 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot) if (SimpleDeclarationAST *simple = targetDeclaration->asSimpleDeclaration()) { declarator = simple->declarator_list->value; if (simple->decl_specifier_list) - returnTypeStart = matchFile->startOf(simple->decl_specifier_list->value); + returnTypeStart = targetFile->startOf(simple->decl_specifier_list->value); else - returnTypeStart = matchFile->startOf(declarator); + returnTypeStart = targetFile->startOf(declarator); } else if (FunctionDefinitionAST *def = targetDeclaration->asFunctionDefinition()) { declarator = def->declarator; if (def->decl_specifier_list) - returnTypeStart = matchFile->startOf(def->decl_specifier_list->value); + returnTypeStart = targetFile->startOf(def->decl_specifier_list->value); else - returnTypeStart = matchFile->startOf(declarator); + returnTypeStart = targetFile->startOf(declarator); } if (!newFunction->returnType().isEqualTo(sourceFunction->returnType()) @@ -428,7 +423,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot) FullySpecifiedType type = rewriteType(newFunction->returnType(), &env, control); const QString replacement = overview(type, targetFunction->name()); changes.replace(returnTypeStart, - matchFile->startOf(targetFunctionDeclarator->lparen_token), + targetFile->startOf(targetFunctionDeclarator->lparen_token), replacement); } } @@ -478,35 +473,35 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot) ParameterDeclarationAST *targetParamAst = targetParameterDeclIt->value; int parameterNameEnd = 0; if (targetParamAst->declarator) - parameterNameEnd = matchFile->endOf(targetParamAst->declarator); + parameterNameEnd = targetFile->endOf(targetParamAst->declarator); else if (targetParamAst->type_specifier_list) - parameterNameEnd = matchFile->endOf(targetParamAst->type_specifier_list->lastToken() - 1); + parameterNameEnd = targetFile->endOf(targetParamAst->type_specifier_list->lastToken() - 1); else - parameterNameEnd = matchFile->startOf(targetParamAst); + parameterNameEnd = targetFile->startOf(targetParamAst); if (allowChangeType && !targetParam->type().isEqualTo(newParam->type())) { FullySpecifiedType replacementType = rewriteType(newParam->type(), &env, control); const QString replacement = overview(replacementType, replacementName); - changes.replace(matchFile->startOf(targetParamAst), + changes.replace(targetFile->startOf(targetParamAst), parameterNameEnd, replacement); } else if (!namesEqual(targetParam->name(), replacementName)) { DeclaratorIdAST *id = getDeclaratorId(targetParamAst->declarator); QString replacementNameStr = overview(replacementName); if (id) { - changes.replace(matchFile->range(id), replacementNameStr); + changes.replace(targetFile->range(id), replacementNameStr); } else { // add name to unnamed parameter replacementNameStr.prepend(QLatin1Char(' ')); int end; if (targetParamAst->equal_token) { - end = matchFile->startOf(targetParamAst->equal_token); + end = targetFile->startOf(targetParamAst->equal_token); replacementNameStr.append(QLatin1Char(' ')); } else { // one past end on purpose - end = matchFile->startOf(targetParamAst->lastToken()); + end = targetFile->startOf(targetParamAst->lastToken()); } changes.replace(parameterNameEnd, end, replacementNameStr); } @@ -516,15 +511,15 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot) targetParameterDeclIt = firstTargetParameterDeclIt; if (targetParameterDeclIt) { if (newArgCount == 0) { - changes.remove(matchFile->startOf(targetParameterDeclIt->firstToken()), - matchFile->endOf(targetParameterDeclIt->lastToken() - 1)); + changes.remove(targetFile->startOf(targetParameterDeclIt->firstToken()), + targetFile->endOf(targetParameterDeclIt->lastToken() - 1)); } else { // get the last valid argument for (unsigned i = 0; i < newArgCount - 1 && targetParameterDeclIt; ++i) targetParameterDeclIt = targetParameterDeclIt->next; if (targetParameterDeclIt) { - const int start = matchFile->endOf(targetParameterDeclIt->value); - const int end = matchFile->endOf(targetParameterDecl->lastToken() - 1); + const int start = targetFile->endOf(targetParameterDeclIt->value); + const int end = targetFile->endOf(targetParameterDecl->lastToken() - 1); changes.remove(start, end); } } @@ -542,9 +537,9 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot) if (targetParameterDeclIt) { while (targetParameterDeclIt->next) targetParameterDeclIt = targetParameterDeclIt->next; - changes.insert(matchFile->endOf(targetParameterDeclIt->value), newParams); + changes.insert(targetFile->endOf(targetParameterDeclIt->value), newParams); } else { - changes.insert(matchFile->endOf(targetFunctionDeclarator->lparen_token), newParams); + changes.insert(targetFile->endOf(targetFunctionDeclarator->lparen_token), newParams); } } } @@ -560,12 +555,12 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot) cvString += QLatin1Char(' '); cvString += QLatin1String("volatile"); } - const int rparenEnd = matchFile->endOf(targetFunctionDeclarator->rparen_token); + const int rparenEnd = targetFile->endOf(targetFunctionDeclarator->rparen_token); if (targetFunctionDeclarator->cv_qualifier_list) { - const int cvEnd = matchFile->endOf(targetFunctionDeclarator->cv_qualifier_list->lastToken() - 1); + const int cvEnd = targetFile->endOf(targetFunctionDeclarator->cv_qualifier_list->lastToken() - 1); // if the qualifies changed, replace if (!cvString.isEmpty()) { - changes.replace(matchFile->startOf(targetFunctionDeclarator->cv_qualifier_list->firstToken()), + changes.replace(targetFile->startOf(targetFunctionDeclarator->cv_qualifier_list->firstToken()), cvEnd, cvString); } else { // remove diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.h b/src/plugins/cppeditor/cppfunctiondecldeflink.h index 5de47afb91..a75e71f3ef 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.h +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.h @@ -100,7 +100,7 @@ public: CPlusPlus::DeclarationAST *sourceDeclaration; CPlusPlus::FunctionDeclaratorAST *sourceFunctionDeclarator; - QSharedPointer<CppTools::CppRefactoringFile> targetFile; + CppTools::CppRefactoringFileConstPtr targetFile; CPlusPlus::Function *targetFunction; CPlusPlus::DeclarationAST *targetDeclaration; CPlusPlus::FunctionDeclaratorAST *targetFunctionDeclarator; diff --git a/src/plugins/cppeditor/cppinsertdecldef.cpp b/src/plugins/cppeditor/cppinsertdecldef.cpp index 7382b5abd7..a5676d2a10 100644 --- a/src/plugins/cppeditor/cppinsertdecldef.cpp +++ b/src/plugins/cppeditor/cppinsertdecldef.cpp @@ -80,25 +80,24 @@ public: "Add %1 Declaration").arg(type)); } - void performChanges(CppRefactoringFile *, CppRefactoringChanges *refactoring) + void performChanges(const CppRefactoringFilePtr &, + const CppRefactoringChanges &refactoring) { InsertionPointLocator locator(refactoring); const InsertionLocation loc = locator.methodDeclarationInClass( m_targetFileName, m_targetSymbol, m_xsSpec); Q_ASSERT(loc.isValid()); - CppRefactoringFile targetFile = refactoring->file(m_targetFileName); - int targetPosition1 = targetFile.position(loc.line(), loc.column()); - int targetPosition2 = qMax(0, targetFile.position(loc.line(), 1) - 1); + CppRefactoringFilePtr targetFile = refactoring.file(m_targetFileName); + int targetPosition1 = targetFile->position(loc.line(), loc.column()); + int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1); Utils::ChangeSet target; target.insert(targetPosition1, loc.prefix() + m_decl); - targetFile.change(target); - targetFile.indent(Utils::ChangeSet::Range(targetPosition2, targetPosition1)); - - const int prefixLineCount = loc.prefix().count(QLatin1Char('\n')); - refactoring->activateEditor(m_targetFileName, loc.line() + prefixLineCount, - qMax(((int) loc.column()) - 1, 0)); + targetFile->setChangeSet(target); + targetFile->appendIndentRange(Utils::ChangeSet::Range(targetPosition2, targetPosition1)); + targetFile->setOpenEditor(true, targetPosition1); + targetFile->apply(); } private: @@ -114,7 +113,7 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match( const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface) { const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); FunctionDefinitionAST *funDef = 0; int idx = 0; @@ -122,7 +121,7 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match( AST *node = path.at(idx); if (idx > 1) { if (DeclaratorIdAST *declId = node->asDeclaratorId()) { - if (file.isCursorOn(declId)) { + if (file->isCursorOn(declId)) { if (FunctionDefinitionAST *candidate = path.at(idx - 2)->asFunctionDefinition()) { if (funDef) { return noResult(); @@ -230,12 +229,12 @@ public: .arg(dir.relativeFilePath(m_loc.fileName()))); } - void performChanges(CppRefactoringFile *, - CppRefactoringChanges *refactoring) + void performChanges(const CppRefactoringFilePtr &, + const CppRefactoringChanges &refactoring) { Q_ASSERT(m_loc.isValid()); - CppRefactoringFile targetFile = refactoring->file(m_loc.fileName()); + CppRefactoringFilePtr targetFile = refactoring.file(m_loc.fileName()); Overview oo; oo.setShowFunctionSignatures(true); @@ -243,7 +242,7 @@ public: oo.setShowArgumentNames(true); // make target lookup context - Document::Ptr targetDoc = targetFile.cppDocument(); + Document::Ptr targetDoc = targetFile->cppDocument(); Scope *targetScope = targetDoc->scopeAt(m_loc.line(), m_loc.column()); LookupContext targetContext(targetDoc, assistInterface()->snapshot()); ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope); @@ -272,18 +271,15 @@ public: QString defText = oo.prettyType(tn, name) + "\n{\n}"; - int targetPos = targetFile.position(m_loc.line(), m_loc.column()); - int targetPos2 = qMax(0, targetFile.position(m_loc.line(), 1) - 1); + int targetPos = targetFile->position(m_loc.line(), m_loc.column()); + int targetPos2 = qMax(0, targetFile->position(m_loc.line(), 1) - 1); Utils::ChangeSet target; target.insert(targetPos, m_loc.prefix() + defText + m_loc.suffix()); - targetFile.change(target); - targetFile.indent(Utils::ChangeSet::Range(targetPos2, targetPos)); - - const int prefixLineCount = m_loc.prefix().count(QLatin1Char('\n')); - refactoring->activateEditor(m_loc.fileName(), - m_loc.line() + prefixLineCount, - 0); + targetFile->setChangeSet(target); + targetFile->appendIndentRange(Utils::ChangeSet::Range(targetPos2, targetPos)); + targetFile->setOpenEditor(true, targetPos); + targetFile->apply(); } private: @@ -297,7 +293,7 @@ QList<CppQuickFixOperation::Ptr> DefFromDecl::match( const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface) { const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); int idx = path.size() - 1; for (; idx >= 0; --idx) { @@ -311,9 +307,9 @@ QList<CppQuickFixOperation::Ptr> DefFromDecl::match( && decl->enclosingScope() && decl->enclosingScope()->isClass()) { DeclaratorAST *declarator = simpleDecl->declarator_list->value; - if (file.isCursorOn(declarator->core_declarator)) { + if (file->isCursorOn(declarator->core_declarator)) { CppRefactoringChanges refactoring(interface->snapshot()); - InsertionPointLocator locator(&refactoring); + InsertionPointLocator locator(refactoring); QList<CppQuickFixOperation::Ptr> results; foreach (const InsertionLocation &loc, locator.methodDefinition(decl)) { if (loc.isValid()) diff --git a/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp b/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp index ed1d99276b..108164da93 100644 --- a/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp +++ b/src/plugins/cppeditor/cppinsertqtpropertymembers.cpp @@ -71,24 +71,23 @@ QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match( if (!klass) return noResult(); - CppRefactoringChanges refactoring(interface->snapshot()); - const CppRefactoringFile &file = refactoring.file(interface->file()->fileName()); - const QString propertyName = file.textOf(qtPropertyDeclaration->property_name); + CppRefactoringFilePtr file = interface->currentFile(); + const QString propertyName = file->textOf(qtPropertyDeclaration->property_name); QString getterName; QString setterName; QString signalName; int generateFlags = 0; for (QtPropertyDeclarationItemListAST *it = qtPropertyDeclaration->property_declaration_item_list; it; it = it->next) { - const QString tokenString = file.tokenAt(it->value->item_name_token).spell(); + const QString tokenString = file->tokenAt(it->value->item_name_token).spell(); if (tokenString == QLatin1String("READ")) { - getterName = file.textOf(it->value->expression); + getterName = file->textOf(it->value->expression); generateFlags |= GenerateGetter; } else if (tokenString == QLatin1String("WRITE")) { - setterName = file.textOf(it->value->expression); + setterName = file->textOf(it->value->expression); generateFlags |= GenerateSetter; } else if (tokenString == QLatin1String("NOTIFY")) { - signalName = file.textOf(it->value->expression); + signalName = file->textOf(it->value->expression); generateFlags |= GenerateSignal; } } @@ -143,7 +142,8 @@ InsertQtPropertyMembers::Operation::Operation( setDescription(desc); } -void InsertQtPropertyMembers::Operation::performChanges(CppRefactoringFile *file, CppRefactoringChanges *refactoring) +void InsertQtPropertyMembers::Operation::performChanges(const CppRefactoringFilePtr &file, + const CppRefactoringChanges &refactoring) { InsertionPointLocator locator(refactoring); Utils::ChangeSet declarations; @@ -190,13 +190,14 @@ void InsertQtPropertyMembers::Operation::performChanges(CppRefactoringFile *file insertAndIndent(file, &declarations, storageLoc, storageDeclaration); } - file->change(declarations); + file->setChangeSet(declarations); + file->apply(); } -void InsertQtPropertyMembers::Operation::insertAndIndent(RefactoringFile *file, ChangeSet *changeSet, const InsertionLocation &loc, const QString &text) +void InsertQtPropertyMembers::Operation::insertAndIndent(const RefactoringFilePtr &file, ChangeSet *changeSet, const InsertionLocation &loc, const QString &text) { int targetPosition1 = file->position(loc.line(), loc.column()); int targetPosition2 = qMax(0, file->position(loc.line(), 1) - 1); changeSet->insert(targetPosition1, loc.prefix() + text + loc.suffix()); - file->indent(Utils::ChangeSet::Range(targetPosition2, targetPosition1)); + file->appendIndentRange(Utils::ChangeSet::Range(targetPosition2, targetPosition1)); } diff --git a/src/plugins/cppeditor/cppinsertqtpropertymembers.h b/src/plugins/cppeditor/cppinsertqtpropertymembers.h index 785ac87ba1..6e90d14a69 100644 --- a/src/plugins/cppeditor/cppinsertqtpropertymembers.h +++ b/src/plugins/cppeditor/cppinsertqtpropertymembers.h @@ -44,6 +44,7 @@ class Class; namespace TextEditor { class RefactoringFile; +typedef QSharedPointer<RefactoringFile> RefactoringFilePtr; } namespace Utils { @@ -83,11 +84,11 @@ private: const QString &getterName, const QString &setterName, const QString &signalName, const QString &storageName); - virtual void performChanges(CppTools::CppRefactoringFile *file, - CppTools::CppRefactoringChanges *refactoring); + virtual void performChanges(const CppTools::CppRefactoringFilePtr &file, + const CppTools::CppRefactoringChanges &refactoring); private: - void insertAndIndent(TextEditor::RefactoringFile *file, Utils::ChangeSet *changeSet, + void insertAndIndent(const TextEditor::RefactoringFilePtr &file, Utils::ChangeSet *changeSet, const CppTools::InsertionLocation &loc, const QString &text); CPlusPlus::QtPropertyDeclarationAST *m_declaration; diff --git a/src/plugins/cppeditor/cppquickfix.cpp b/src/plugins/cppeditor/cppquickfix.cpp index ae63fb43ed..96e4d2178a 100644 --- a/src/plugins/cppeditor/cppquickfix.cpp +++ b/src/plugins/cppeditor/cppquickfix.cpp @@ -70,9 +70,9 @@ CppQuickFixOperation::~CppQuickFixOperation() void CppQuickFixOperation::perform() { CppRefactoringChanges refactoring(m_interface->snapshot()); - CppRefactoringFile current = refactoring.file(fileName()); + CppRefactoringFilePtr current = refactoring.file(fileName()); - performChanges(¤t, &refactoring); + performChanges(current, refactoring); } const CppQuickFixAssistInterface *CppQuickFixOperation::assistInterface() const diff --git a/src/plugins/cppeditor/cppquickfix.h b/src/plugins/cppeditor/cppquickfix.h index 3d93b41f28..af5ec93101 100644 --- a/src/plugins/cppeditor/cppquickfix.h +++ b/src/plugins/cppeditor/cppquickfix.h @@ -40,6 +40,7 @@ namespace CppTools { class CppModelManagerInterface; class CppRefactoringFile; class CppRefactoringChanges; + typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr; } // namespace CppTools namespace ExtensionSystem { @@ -63,8 +64,8 @@ public: virtual void perform(); protected: - virtual void performChanges(CppTools::CppRefactoringFile *currentFile, - CppTools::CppRefactoringChanges *refactoring) = 0; + virtual void performChanges(const CppTools::CppRefactoringFilePtr ¤tFile, + const CppTools::CppRefactoringChanges &refactoring) = 0; QString fileName() const; diff --git a/src/plugins/cppeditor/cppquickfixassistant.cpp b/src/plugins/cppeditor/cppquickfixassistant.cpp index dccf0af809..9f02ddb066 100644 --- a/src/plugins/cppeditor/cppquickfixassistant.cpp +++ b/src/plugins/cppeditor/cppquickfixassistant.cpp @@ -105,6 +105,7 @@ CppQuickFixAssistInterface::CppQuickFixAssistInterface(CPPEditorWidget *editor, , m_editor(editor) , m_semanticInfo(editor->semanticInfo()) , m_snapshot(CPlusPlus::CppModelManagerInterface::instance()->snapshot()) + , m_currentFile(CppRefactoringChanges::file(editor, m_semanticInfo.doc)) , m_context(m_semanticInfo.doc, m_snapshot) { CPlusPlus::ASTPath astPath(m_semanticInfo.doc); @@ -136,19 +137,17 @@ CPPEditorWidget *CppQuickFixAssistInterface::editor() const return m_editor; } -const CppRefactoringFile CppQuickFixAssistInterface::currentFile() const +CppRefactoringFilePtr CppQuickFixAssistInterface::currentFile() const { - CppRefactoringFile file(m_editor); - file.setCppDocument(m_semanticInfo.doc); - return file; + return m_currentFile; } bool CppQuickFixAssistInterface::isCursorOn(unsigned tokenIndex) const { - return currentFile().isCursorOn(tokenIndex); + return currentFile()->isCursorOn(tokenIndex); } bool CppQuickFixAssistInterface::isCursorOn(const CPlusPlus::AST *ast) const { - return currentFile().isCursorOn(ast); + return currentFile()->isCursorOn(ast); } diff --git a/src/plugins/cppeditor/cppquickfixassistant.h b/src/plugins/cppeditor/cppquickfixassistant.h index f08a9ea610..44dd5add8e 100644 --- a/src/plugins/cppeditor/cppquickfixassistant.h +++ b/src/plugins/cppeditor/cppquickfixassistant.h @@ -44,6 +44,7 @@ namespace CppTools { class CppRefactoringFile; +typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr; } namespace CppEditor { @@ -62,7 +63,7 @@ public: const CPlusPlus::LookupContext &context() const; CPPEditorWidget *editor() const; - const CppTools::CppRefactoringFile currentFile() const; + CppTools::CppRefactoringFilePtr currentFile() const; bool isCursorOn(unsigned tokenIndex) const; bool isCursorOn(const CPlusPlus::AST *ast) const; @@ -71,6 +72,7 @@ private: CPPEditorWidget *m_editor; CppEditor::Internal::SemanticInfo m_semanticInfo; CPlusPlus::Snapshot m_snapshot; + CppTools::CppRefactoringFilePtr m_currentFile; CPlusPlus::LookupContext m_context; QList<CPlusPlus::AST *> m_path; }; diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index f5f5b82d5e..c169e32489 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -89,7 +89,7 @@ public: virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) { QList<CppQuickFixOperation::Ptr> result; - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); const QList<AST *> &path = interface->path(); int index = path.size() - 1; @@ -100,7 +100,7 @@ public: return result; Kind invertToken; - switch (file.tokenAt(binary->binary_op_token).kind()) { + switch (file->tokenAt(binary->binary_op_token).kind()) { case T_LESS_EQUAL: invertToken = T_GREATER; break; @@ -153,7 +153,7 @@ private: // check for ! before parentheses if (nested && priority - 2 >= 0) { negation = interface->path()[priority - 2]->asUnaryExpression(); - if (negation && ! interface->currentFile().tokenAt(negation->unary_op_token).is(T_EXCLAIM)) + if (negation && ! interface->currentFile()->tokenAt(negation->unary_op_token).is(T_EXCLAIM)) negation = 0; } } @@ -163,7 +163,7 @@ private: return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; if (negation) { @@ -176,7 +176,8 @@ private: changes.insert(currentFile->endOf(binary), ")"); } changes.replace(currentFile->range(binary->binary_op_token), replacement); - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } }; }; @@ -197,7 +198,7 @@ public: { QList<QuickFixOperation::Ptr> result; const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); int index = path.size() - 1; BinaryExpressionAST *binary = path.at(index)->asBinaryExpression(); @@ -207,7 +208,7 @@ public: return result; Kind flipToken; - switch (file.tokenAt(binary->binary_op_token).kind()) { + switch (file->tokenAt(binary->binary_op_token).kind()) { case T_LESS_EQUAL: flipToken = T_GREATER_EQUAL; break; @@ -262,7 +263,7 @@ private: return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -270,7 +271,8 @@ private: if (! replacement.isEmpty()) changes.replace(currentFile->range(binary->binary_op_token), replacement); - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } private: @@ -296,7 +298,7 @@ public: QList<QuickFixOperation::Ptr> result; BinaryExpressionAST *expression = 0; const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); int index = path.size() - 1; for (; index != -1; --index) { @@ -314,9 +316,9 @@ public: QSharedPointer<Operation> op(new Operation(interface)); if (expression->match(op->pattern, &matcher) && - file.tokenAt(op->pattern->binary_op_token).is(T_AMPER_AMPER) && - file.tokenAt(op->left->unary_op_token).is(T_EXCLAIM) && - file.tokenAt(op->right->unary_op_token).is(T_EXCLAIM)) { + file->tokenAt(op->pattern->binary_op_token).is(T_AMPER_AMPER) && + file->tokenAt(op->left->unary_op_token).is(T_EXCLAIM) && + file->tokenAt(op->right->unary_op_token).is(T_EXCLAIM)) { op->setDescription(QApplication::translate("CppTools::QuickFix", "Rewrite Condition Using ||")); op->setPriority(index); result.append(op); @@ -343,7 +345,7 @@ private: pattern = mk->BinaryExpression(left, right); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||")); @@ -354,8 +356,9 @@ private: changes.insert(start, QLatin1String("!(")); changes.insert(end, QLatin1String(")")); - currentFile->change(changes); - currentFile->indent(currentFile->range(pattern)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(currentFile->range(pattern)); + currentFile->apply(); } }; @@ -408,7 +411,7 @@ public: QList<CppQuickFixOperation::Ptr> result; CoreDeclaratorAST *core_declarator = 0; const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); for (int index = path.size() - 1; index != -1; --index) { AST *node = path.at(index); @@ -420,10 +423,10 @@ public: if (checkDeclaration(simpleDecl)) { SimpleDeclarationAST *declaration = simpleDecl; - const int cursorPosition = file.cursor().selectionStart(); + const int cursorPosition = file->cursor().selectionStart(); - const int startOfDeclSpecifier = file.startOf(declaration->decl_specifier_list->firstToken()); - const int endOfDeclSpecifier = file.endOf(declaration->decl_specifier_list->lastToken() - 1); + const int startOfDeclSpecifier = file->startOf(declaration->decl_specifier_list->firstToken()); + const int endOfDeclSpecifier = file->endOf(declaration->decl_specifier_list->lastToken() - 1); if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) { // the AST node under cursor is a specifier. @@ -455,7 +458,7 @@ private: "Split Declaration")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -481,8 +484,9 @@ private: prevDeclarator = declarator; } - currentFile->change(changes); - currentFile->indent(currentFile->range(declaration)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(currentFile->range(declaration)); + currentFile->apply(); } private: @@ -547,7 +551,7 @@ private: "Add Curly Braces")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -557,8 +561,9 @@ private: const int end = currentFile->endOf(_statement->lastToken() - 1); changes.insert(end, "\n}"); - currentFile->change(changes); - currentFile->indent(Utils::ChangeSet::Range(start, end)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(Utils::ChangeSet::Range(start, end)); + currentFile->apply(); } private: @@ -620,7 +625,7 @@ private: pattern = mk.IfStatement(condition); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -630,8 +635,9 @@ private: changes.move(currentFile->range(condition), insertPos); changes.insert(insertPos, QLatin1String(";\n")); - currentFile->change(changes); - currentFile->indent(currentFile->range(pattern)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(currentFile->range(pattern)); + currentFile->apply(); } ASTMatcher matcher; @@ -704,7 +710,7 @@ private: pattern = mk.WhileStatement(condition); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -717,8 +723,9 @@ private: changes.copy(currentFile->range(core), insertPos); changes.insert(insertPos, QLatin1String(";\n")); - currentFile->change(changes); - currentFile->indent(currentFile->range(pattern)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(currentFile->range(pattern)); + currentFile->apply(); } ASTMatcher matcher; @@ -780,7 +787,7 @@ public: if (! condition) return noResult(); - Token binaryToken = interface->currentFile().tokenAt(condition->binary_op_token); + Token binaryToken = interface->currentFile()->tokenAt(condition->binary_op_token); // only accept a chain of ||s or &&s - no mixing if (! splitKind) { @@ -815,7 +822,7 @@ private: "Split if Statement")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { const Token binaryToken = currentFile->tokenAt(condition->binary_op_token); @@ -825,7 +832,7 @@ private: splitOrCondition(currentFile); } - void splitAndCondition(CppRefactoringFile *currentFile) + void splitAndCondition(CppRefactoringFilePtr currentFile) { ChangeSet changes; @@ -838,11 +845,12 @@ private: changes.remove(lExprEnd, currentFile->startOf(condition->right_expression)); changes.insert(currentFile->endOf(pattern), QLatin1String("\n}")); - currentFile->change(changes); - currentFile->indent(currentFile->range(pattern)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(currentFile->range(pattern)); + currentFile->apply(); } - void splitOrCondition(CppRefactoringFile *currentFile) + void splitOrCondition(CppRefactoringFilePtr currentFile) { ChangeSet changes; @@ -866,8 +874,9 @@ private: const int lExprEnd = currentFile->endOf(condition->left_expression); changes.remove(lExprEnd, currentFile->startOf(condition->right_expression)); - currentFile->change(changes); - currentFile->indent(currentFile->range(pattern)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(currentFile->range(pattern)); + currentFile->apply(); } private: @@ -897,7 +906,7 @@ public: ExpressionAST *literal = 0; Type type = TypeNone; const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); if (path.isEmpty()) return noResult(); // nothing to do @@ -906,7 +915,7 @@ public: if (! literal) { literal = path.last()->asNumericLiteral(); - if (!literal || !file.tokenAt(literal->asNumericLiteral()->literal_token).is(T_CHAR_LITERAL)) + if (!literal || !file->tokenAt(literal->asNumericLiteral()->literal_token).is(T_CHAR_LITERAL)) return noResult(); else type = TypeChar; @@ -919,7 +928,7 @@ public: if (call->base_expression) { if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) { if (SimpleNameAST *functionName = idExpr->name->asSimpleName()) { - const QByteArray id(file.tokenAt(functionName->identifier_token).identifier->chars()); + const QByteArray id(file->tokenAt(functionName->identifier_token).identifier->chars()); if (id == "QT_TRANSLATE_NOOP" || id == "tr" || id == "trUtf8" || (type == TypeString && (id == "QLatin1String" || id == "QLatin1Literal")) @@ -932,7 +941,7 @@ public: } if (type == TypeString) { - if (file.charAt(file.startOf(literal)) == QLatin1Char('@')) + if (file->charAt(file->startOf(literal)) == QLatin1Char('@')) type = TypeObjCString; } return singleResult(new Operation(interface, @@ -959,7 +968,7 @@ private: "Enclose in QLatin1String(...)")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -974,7 +983,8 @@ private: changes.insert(currentFile->endOf(literal), ")"); - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } private: @@ -1019,7 +1029,7 @@ public: if (call->base_expression) { if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) { if (SimpleNameAST *functionName = idExpr->name->asSimpleName()) { - const QByteArray id(interface->currentFile().tokenAt(functionName->identifier_token).identifier->chars()); + const QByteArray id(interface->currentFile()->tokenAt(functionName->identifier_token).identifier->chars()); if (id == "tr" || id == "trUtf8" || id == "translate" @@ -1083,7 +1093,7 @@ private: setDescription(QApplication::translate("CppTools::QuickFix", "Mark as Translatable")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -1100,7 +1110,8 @@ private: changes.insert(startPos, replacement); changes.insert(currentFile->endOf(m_literal), QLatin1String(")")); - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } private: @@ -1125,7 +1136,7 @@ class CStringToNSString: public CppQuickFixFactory public: virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) { - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); if (interface->editor()->mimeType() != CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE) return noResult(); @@ -1142,7 +1153,7 @@ public: if (! stringLiteral) return noResult(); - else if (file.charAt(file.startOf(stringLiteral)) == QLatin1Char('@')) + else if (file->charAt(file->startOf(stringLiteral)) == QLatin1Char('@')) return noResult(); // it's already an objc string literal. else if (path.size() > 1) { @@ -1150,7 +1161,7 @@ public: if (call->base_expression) { if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) { if (SimpleNameAST *functionName = idExpr->name->asSimpleName()) { - const QByteArray id(interface->currentFile().tokenAt(functionName->identifier_token).identifier->chars()); + const QByteArray id(interface->currentFile()->tokenAt(functionName->identifier_token).identifier->chars()); if (id == "QLatin1String" || id == "QLatin1Literal") qlatin1Call = call; @@ -1176,7 +1187,7 @@ private: "Convert to Objective-C String Literal")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; @@ -1187,7 +1198,8 @@ private: changes.insert(currentFile->startOf(stringLiteral), "@"); } - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } private: @@ -1222,7 +1234,7 @@ public: QList<QuickFixOperation::Ptr> result; const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); if (path.isEmpty()) return result; // nothing to do @@ -1232,7 +1244,7 @@ public: if (! literal) return result; - Token token = file.tokenAt(literal->asNumericLiteral()->literal_token); + Token token = file->tokenAt(literal->asNumericLiteral()->literal_token); if (!token.is(T_NUMERIC_LITERAL)) return result; const NumericLiteral *numeric = token.number; @@ -1254,7 +1266,7 @@ public: return result; const int priority = path.size() - 1; // very high priority - const int start = file.startOf(literal); + const int start = file->startOf(literal); const char * const str = numeric->chars(); if (!numeric->isHex()) { @@ -1328,11 +1340,12 @@ private: , replacement(replacement) {} - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &) { ChangeSet changes; changes.replace(start, end, replacement); - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } protected: @@ -1407,7 +1420,8 @@ private: "#include Header File")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, + const CppRefactoringChanges &) { Q_ASSERT(fwdClass != 0); @@ -1464,7 +1478,8 @@ private: Utils::ChangeSet changes; changes.insert(pos, QString("#include <%1>\n").arg(QFileInfo(best).fileName())); - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } } @@ -1488,15 +1503,15 @@ public: virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface) { const QList<AST *> &path = interface->path(); - const CppRefactoringFile &file = interface->currentFile(); + CppRefactoringFilePtr file = interface->currentFile(); for (int index = path.size() - 1; index != -1; --index) { if (BinaryExpressionAST *binary = path.at(index)->asBinaryExpression()) { - if (binary->left_expression && binary->right_expression && file.tokenAt(binary->binary_op_token).is(T_EQUAL)) { + if (binary->left_expression && binary->right_expression && file->tokenAt(binary->binary_op_token).is(T_EQUAL)) { IdExpressionAST *idExpr = binary->left_expression->asIdExpression(); if (interface->isCursorOn(binary->left_expression) && idExpr && idExpr->name->asSimpleName() != 0) { SimpleNameAST *nameAST = idExpr->name->asSimpleName(); - const QList<LookupItem> results = interface->context().lookup(nameAST->name, file.scopeAt(nameAST->firstToken())); + const QList<LookupItem> results = interface->context().lookup(nameAST->name, file->scopeAt(nameAST->firstToken())); Declaration *decl = 0; foreach (const LookupItem &r, results) { if (! r.declaration()) @@ -1531,7 +1546,8 @@ private: setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration")); } - virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr ¤tFile, + const CppRefactoringChanges &) { TypeOfExpression typeOfExpression; typeOfExpression.init(assistInterface()->semanticInfo().doc, @@ -1565,7 +1581,8 @@ private: Utils::ChangeSet changes; changes.insert(currentFile->startOf(binaryAST), ty); - currentFile->change(changes); + currentFile->setChangeSet(changes); + currentFile->apply(); } } } @@ -1626,7 +1643,8 @@ private: "Convert to Camel Case")); } - virtual void performChanges(CppRefactoringFile *, CppRefactoringChanges *) + virtual void performChanges(const CppRefactoringFilePtr &, + const CppRefactoringChanges &) { for (int i = 1; i < m_name.length(); ++i) { QCharRef c = m_name[i]; diff --git a/src/plugins/cpptools/cpprefactoringchanges.cpp b/src/plugins/cpptools/cpprefactoringchanges.cpp index c92aa862d2..af73d52d69 100644 --- a/src/plugins/cpptools/cpprefactoringchanges.cpp +++ b/src/plugins/cpptools/cpprefactoringchanges.cpp @@ -49,64 +49,101 @@ using namespace CPlusPlus; using namespace CppTools; using namespace Utils; +class CppTools::CppRefactoringChangesData : public TextEditor::RefactoringChangesData +{ +public: + CppRefactoringChangesData(const Snapshot &snapshot) + : m_snapshot(snapshot) + , m_modelManager(Internal::CppModelManager::instance()) + , m_workingCopy(m_modelManager->workingCopy()) + {} + + virtual void indentSelection(const QTextCursor &selection, + const QString &fileName, + const TextEditor::BaseTextEditorWidget *textEditor) const + { + // ### shares code with CPPEditor::indent() + QTextDocument *doc = selection.document(); + + QTextBlock block = doc->findBlock(selection.selectionStart()); + const QTextBlock end = doc->findBlock(selection.selectionEnd()).next(); + + const TextEditor::TabSettings &tabSettings = + ProjectExplorer::actualTabSettings(fileName, textEditor); + // TODO: add similar method like above one + CppTools::QtStyleCodeFormatter codeFormatter(tabSettings, + CppToolsSettings::instance()->cppCodeStylePreferences()->settings()); + codeFormatter.updateStateUntil(block); + + do { + int indent; + int padding; + codeFormatter.indentFor(block, &indent, &padding); + tabSettings.indentLine(block, indent + padding, padding); + codeFormatter.updateLineStateChange(block); + block = block.next(); + } while (block.isValid() && block != end); + + } + + virtual void fileChanged(const QString &fileName) + { + m_modelManager->updateSourceFiles(QStringList(fileName)); + } + + CPlusPlus::Snapshot m_snapshot; + CPlusPlus::CppModelManagerInterface *m_modelManager; + CPlusPlus::CppModelManagerInterface::WorkingCopy m_workingCopy; + +}; + CppRefactoringChanges::CppRefactoringChanges(const Snapshot &snapshot) - : m_snapshot(snapshot) - , m_modelManager(Internal::CppModelManager::instance()) + : RefactoringChanges(new CppRefactoringChangesData(snapshot)) { - Q_ASSERT(m_modelManager); - m_workingCopy = m_modelManager->workingCopy(); } -const Snapshot &CppRefactoringChanges::snapshot() const +CppRefactoringChangesData *CppRefactoringChanges::data() const { - return m_snapshot; + return static_cast<CppRefactoringChangesData *>(m_data.data()); } -CppRefactoringFile CppRefactoringChanges::file(const QString &fileName) +CppRefactoringFilePtr CppRefactoringChanges::file(TextEditor::BaseTextEditorWidget *editor, const Document::Ptr &document) { - return CppRefactoringFile(fileName, this); + CppRefactoringFilePtr result(new CppRefactoringFile(editor)); + result->setCppDocument(document); + return result; } -void CppRefactoringChanges::indentSelection(const QTextCursor &selection, - const QString &fileName, - const TextEditor::BaseTextEditorWidget *textEditor) const +CppRefactoringFilePtr CppRefactoringChanges::file(const QString &fileName) const { - // ### shares code with CPPEditor::indent() - QTextDocument *doc = selection.document(); + CppRefactoringFilePtr result(new CppRefactoringFile(fileName, m_data)); + return result; +} - QTextBlock block = doc->findBlock(selection.selectionStart()); - const QTextBlock end = doc->findBlock(selection.selectionEnd()).next(); +CppRefactoringFileConstPtr CppRefactoringChanges::fileNoEditor(const QString &fileName) const +{ + QTextDocument *document = 0; + if (data()->m_workingCopy.contains(fileName)) + document = new QTextDocument(data()->m_workingCopy.source(fileName)); + CppRefactoringFilePtr result(new CppRefactoringFile(document, fileName)); + result->m_data = m_data; - const TextEditor::TabSettings &tabSettings = - ProjectExplorer::actualTabSettings(fileName, textEditor); - // TODO: add similar method like above one - CppTools::QtStyleCodeFormatter codeFormatter(tabSettings, - CppToolsSettings::instance()->cppCodeStylePreferences()->settings()); - codeFormatter.updateStateUntil(block); + Document::Ptr cppDocument = data()->m_snapshot.document(fileName); + if (cppDocument) + result->setCppDocument(cppDocument); - do { - int indent; - int padding; - codeFormatter.indentFor(block, &indent, &padding); - tabSettings.indentLine(block, indent + padding, padding); - codeFormatter.updateLineStateChange(block); - block = block.next(); - } while (block.isValid() && block != end); + return result; } -void CppRefactoringChanges::fileChanged(const QString &fileName) +const Snapshot &CppRefactoringChanges::snapshot() const { - m_modelManager->updateSourceFiles(QStringList(fileName)); + return data()->m_snapshot; } - -CppRefactoringFile::CppRefactoringFile() -{ } - -CppRefactoringFile::CppRefactoringFile(const QString &fileName, CppRefactoringChanges *refactoringChanges) - : RefactoringFile(fileName, refactoringChanges) +CppRefactoringFile::CppRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data) + : RefactoringFile(fileName, data) { - const Snapshot &snapshot = refactoringChanges->snapshot(); + const Snapshot &snapshot = this->data()->m_snapshot; m_cppDocument = snapshot.document(fileName); } @@ -124,7 +161,7 @@ Document::Ptr CppRefactoringFile::cppDocument() const !m_cppDocument->translationUnit()->ast()) { const QString source = document()->toPlainText(); const QString name = fileName(); - const Snapshot &snapshot = refactoringChanges()->snapshot(); + const Snapshot &snapshot = data()->m_snapshot; const QByteArray contents = snapshot.preprocessedCode(source, name); m_cppDocument = snapshot.documentFromSource(contents, name); @@ -233,7 +270,13 @@ const Token &CppRefactoringFile::tokenAt(unsigned index) const return cppDocument()->translationUnit()->tokenAt(index); } -CppRefactoringChanges *CppRefactoringFile::refactoringChanges() const +CppRefactoringChangesData *CppRefactoringFile::data() const +{ + return static_cast<CppRefactoringChangesData *>(m_data.data()); +} + +void CppRefactoringFile::fileChanged() { - return static_cast<CppRefactoringChanges *>(m_refactoringChanges); + m_cppDocument.clear(); + RefactoringFile::fileChanged(); } diff --git a/src/plugins/cpptools/cpprefactoringchanges.h b/src/plugins/cpptools/cpprefactoringchanges.h index c32e4e5c99..610d4cb66e 100644 --- a/src/plugins/cpptools/cpprefactoringchanges.h +++ b/src/plugins/cpptools/cpprefactoringchanges.h @@ -45,14 +45,14 @@ namespace CppTools { class CppRefactoringChanges; +class CppRefactoringFile; +class CppRefactoringChangesData; +typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr; +typedef QSharedPointer<const CppRefactoringFile> CppRefactoringFileConstPtr; class CPPTOOLS_EXPORT CppRefactoringFile: public TextEditor::RefactoringFile { public: - CppRefactoringFile(); - CppRefactoringFile(QTextDocument *document, const QString &fileName = QString()); - CppRefactoringFile(TextEditor::BaseTextEditorWidget *editor); - CPlusPlus::Document::Ptr cppDocument() const; void setCppDocument(CPlusPlus::Document::Ptr document); @@ -78,10 +78,12 @@ public: QString textOf(const CPlusPlus::AST *ast) const; protected: - CppRefactoringFile(const QString &fileName, CppRefactoringChanges *refactoringChanges); + CppRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data); + CppRefactoringFile(QTextDocument *document, const QString &fileName); + CppRefactoringFile(TextEditor::BaseTextEditorWidget *editor); -private: - CppRefactoringChanges *refactoringChanges() const; + CppRefactoringChangesData *data() const; + virtual void fileChanged(); mutable CPlusPlus::Document::Ptr m_cppDocument; @@ -93,21 +95,16 @@ class CPPTOOLS_EXPORT CppRefactoringChanges: public TextEditor::RefactoringChang public: CppRefactoringChanges(const CPlusPlus::Snapshot &snapshot); - const CPlusPlus::Snapshot &snapshot() const; - CppRefactoringFile file(const QString &fileName); + static CppRefactoringFilePtr file(TextEditor::BaseTextEditorWidget *editor, + const CPlusPlus::Document::Ptr &document); + CppRefactoringFilePtr file(const QString &fileName) const; + // safe to use from non-gui threads + CppRefactoringFileConstPtr fileNoEditor(const QString &fileName) const; -private: - virtual void indentSelection(const QTextCursor &selection, - const QString &fileName, - const TextEditor::BaseTextEditorWidget *textEditor) const; - virtual void fileChanged(const QString &fileName); + const CPlusPlus::Snapshot &snapshot() const; private: - CPlusPlus::Document::Ptr m_thisDocument; - CPlusPlus::Snapshot m_snapshot; - CPlusPlus::LookupContext m_context; - CPlusPlus::CppModelManagerInterface *m_modelManager; - CPlusPlus::CppModelManagerInterface::WorkingCopy m_workingCopy; + CppRefactoringChangesData *data() const; }; } // namespace CppTools diff --git a/src/plugins/cpptools/insertionpointlocator.cpp b/src/plugins/cpptools/insertionpointlocator.cpp index af8aa1f6e3..5247f9fb06 100644 --- a/src/plugins/cpptools/insertionpointlocator.cpp +++ b/src/plugins/cpptools/insertionpointlocator.cpp @@ -287,7 +287,7 @@ InsertionLocation::InsertionLocation(const QString &fileName, , m_column(column) {} -InsertionPointLocator::InsertionPointLocator(CppRefactoringChanges *refactoringChanges) +InsertionPointLocator::InsertionPointLocator(const CppRefactoringChanges &refactoringChanges) : m_refactoringChanges(refactoringChanges) { } @@ -297,7 +297,7 @@ InsertionLocation InsertionPointLocator::methodDeclarationInClass( const Class *clazz, AccessSpec xsSpec) const { - const Document::Ptr doc = m_refactoringChanges->file(fileName).cppDocument(); + const Document::Ptr doc = m_refactoringChanges.file(fileName)->cppDocument(); if (doc) { FindInClass find(doc, clazz, xsSpec); return find(); @@ -434,11 +434,11 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition( target = candidate; } - Document::Ptr doc = m_refactoringChanges->file(target).cppDocument(); + Document::Ptr doc = m_refactoringChanges.file(target)->cppDocument(); if (doc.isNull()) return result; - Snapshot simplified = m_refactoringChanges->snapshot().simplified(doc); + Snapshot simplified = m_refactoringChanges.snapshot().simplified(doc); if (Symbol *s = simplified.findMatchingDefinition(declaration)) { if (Function *f = s->asFunction()) { if (f->isConst() == declaration->type().isConst() diff --git a/src/plugins/cpptools/insertionpointlocator.h b/src/plugins/cpptools/insertionpointlocator.h index b3506ec55c..7f250e5f08 100644 --- a/src/plugins/cpptools/insertionpointlocator.h +++ b/src/plugins/cpptools/insertionpointlocator.h @@ -39,11 +39,10 @@ #include <CPlusPlusForwardDeclarations.h> #include <cplusplus/CppDocument.h> +#include <cpptools/cpprefactoringchanges.h> namespace CppTools { -class CppRefactoringChanges; - class CPPTOOLS_EXPORT InsertionLocation { public: @@ -100,7 +99,7 @@ public: }; public: - InsertionPointLocator(CppRefactoringChanges *refactoringChanges); + InsertionPointLocator(const CppRefactoringChanges &refactoringChanges); InsertionLocation methodDeclarationInClass(const QString &fileName, const CPlusPlus::Class *clazz, @@ -109,7 +108,7 @@ public: QList<InsertionLocation> methodDefinition(CPlusPlus::Declaration *declaration) const; private: - CppRefactoringChanges *m_refactoringChanges; + CppRefactoringChanges m_refactoringChanges; }; } // namespace CppTools diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp index 0d8eeb24c5..11cfa9e51e 100644 --- a/src/plugins/designer/qtcreatorintegration.cpp +++ b/src/plugins/designer/qtcreatorintegration.cpp @@ -297,7 +297,7 @@ static void addDeclaration(const Snapshot &snapshot, declaration += QLatin1String(";\n"); CppTools::CppRefactoringChanges refactoring(snapshot); - CppTools::InsertionPointLocator find(&refactoring); + CppTools::InsertionPointLocator find(refactoring); const CppTools::InsertionLocation loc = find.methodDeclarationInClass( fileName, cl, CppTools::InsertionPointLocator::PrivateSlot); diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index bf78bed93d..f8baece7e8 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -114,7 +114,8 @@ public: } } - virtual void performChanges(QmlJSRefactoringFile *currentFile, QmlJSRefactoringChanges *refactoring) + virtual void performChanges(QmlJSRefactoringFilePtr currentFile, + const QmlJSRefactoringChanges &refactoring) { QString componentName = m_componentName; QString path = QFileInfo(fileName()).path(); @@ -142,7 +143,7 @@ public: + QLatin1String("}\n"); // stop if we can't create the new file - if (!refactoring->createFile(newFileName, txt)) + if (!refactoring.createFile(newFileName, txt)) return; QString replacement = componentName + QLatin1String(" {\n"); @@ -152,8 +153,9 @@ public: Utils::ChangeSet changes; changes.replace(start, end, replacement); - currentFile->change(changes); - currentFile->indent(Range(start, end + 1)); + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(Range(start, end + 1)); + currentFile->apply(); } }; @@ -163,13 +165,13 @@ public: QList<QmlJSQuickFixOperation::Ptr> ComponentFromObjectDef::match( const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface) { - const int pos = interface->currentFile().cursor().position(); + const int pos = interface->currentFile()->cursor().position(); QList<Node *> path = interface->semanticInfo().rangePath(pos); for (int i = path.size() - 1; i >= 0; --i) { Node *node = path.at(i); if (UiObjectDefinition *objDef = cast<UiObjectDefinition *>(node)) { - if (!interface->currentFile().isCursorOn(objDef->qualifiedTypeNameId)) + if (!interface->currentFile()->isCursorOn(objDef->qualifiedTypeNameId)) return noResult(); // check that the node is not the root node if (i > 0 && !cast<UiProgram*>(path.at(i - 1))) { diff --git a/src/plugins/qmljseditor/qmljsquickfix.cpp b/src/plugins/qmljseditor/qmljsquickfix.cpp index f00a0eddd1..186442dcd0 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.cpp +++ b/src/plugins/qmljseditor/qmljsquickfix.cpp @@ -66,11 +66,10 @@ QmlJSQuickFixOperation::~QmlJSQuickFixOperation() void QmlJSQuickFixOperation::perform() { QmlJSRefactoringChanges refactoring(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>(), - //_state.snapshot()); m_interface->semanticInfo().snapshot); - QmlJSRefactoringFile current = refactoring.file(fileName()); + QmlJSRefactoringFilePtr current = refactoring.file(fileName()); - performChanges(¤t, &refactoring); + performChanges(current, refactoring); } const QmlJSQuickFixAssistInterface *QmlJSQuickFixOperation::assistInterface() const diff --git a/src/plugins/qmljseditor/qmljsquickfix.h b/src/plugins/qmljseditor/qmljsquickfix.h index 99b8b60737..7cdbb79eab 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.h +++ b/src/plugins/qmljseditor/qmljsquickfix.h @@ -79,8 +79,8 @@ public: protected: typedef Utils::ChangeSet::Range Range; - virtual void performChanges(QmlJSTools::QmlJSRefactoringFile *currentFile, - QmlJSTools::QmlJSRefactoringChanges *refactoring) = 0; + virtual void performChanges(QmlJSTools::QmlJSRefactoringFilePtr currentFile, + const QmlJSTools::QmlJSRefactoringChanges &refactoring) = 0; const Internal::QmlJSQuickFixAssistInterface *assistInterface() const; diff --git a/src/plugins/qmljseditor/qmljsquickfixassist.cpp b/src/plugins/qmljseditor/qmljsquickfixassist.cpp index 99a60eaa68..0d30dae873 100644 --- a/src/plugins/qmljseditor/qmljsquickfixassist.cpp +++ b/src/plugins/qmljseditor/qmljsquickfixassist.cpp @@ -51,6 +51,7 @@ QmlJSQuickFixAssistInterface::QmlJSQuickFixAssistInterface(QmlJSTextEditorWidget : DefaultAssistInterface(editor->document(), editor->position(), editor->file(), reason) , m_editor(editor) , m_semanticInfo(editor->semanticInfo()) + , m_currentFile(QmlJSRefactoringChanges::file(m_editor, m_semanticInfo.document)) {} QmlJSQuickFixAssistInterface::~QmlJSQuickFixAssistInterface() @@ -61,9 +62,9 @@ const SemanticInfo &QmlJSQuickFixAssistInterface::semanticInfo() const return m_semanticInfo; } -const QmlJSTools::QmlJSRefactoringFile QmlJSQuickFixAssistInterface::currentFile() const +QmlJSRefactoringFilePtr QmlJSQuickFixAssistInterface::currentFile() const { - return QmlJSRefactoringFile(m_editor, m_semanticInfo.document); + return m_currentFile; } QWidget *QmlJSQuickFixAssistInterface::widget() const diff --git a/src/plugins/qmljseditor/qmljsquickfixassist.h b/src/plugins/qmljseditor/qmljsquickfixassist.h index 3427cb1b41..50d2ec00e5 100644 --- a/src/plugins/qmljseditor/qmljsquickfixassist.h +++ b/src/plugins/qmljseditor/qmljsquickfixassist.h @@ -51,12 +51,13 @@ public: virtual ~QmlJSQuickFixAssistInterface(); const SemanticInfo &semanticInfo() const; - const QmlJSTools::QmlJSRefactoringFile currentFile() const; + QmlJSTools::QmlJSRefactoringFilePtr currentFile() const; QWidget *widget() const; private: QmlJSTextEditorWidget *m_editor; SemanticInfo m_semanticInfo; + QmlJSTools::QmlJSRefactoringFilePtr m_currentFile; }; diff --git a/src/plugins/qmljseditor/qmljsquickfixes.cpp b/src/plugins/qmljseditor/qmljsquickfixes.cpp index 84fd0de6fe..394e8c1d1c 100644 --- a/src/plugins/qmljseditor/qmljsquickfixes.cpp +++ b/src/plugins/qmljseditor/qmljsquickfixes.cpp @@ -70,7 +70,7 @@ public: { UiObjectInitializer *objectInitializer = 0; - const int pos = interface->currentFile().cursor().position(); + const int pos = interface->currentFile()->cursor().position(); if (QmlJS::AST::Node *member = interface->semanticInfo().rangeAt(pos)) { if (QmlJS::AST::UiObjectBinding *b = QmlJS::AST::cast<QmlJS::AST::UiObjectBinding *>(member)) { @@ -104,7 +104,8 @@ private: "Split initializer")); } - virtual void performChanges(QmlJSRefactoringFile *currentFile, QmlJSRefactoringChanges *) + virtual void performChanges(QmlJSRefactoringFilePtr currentFile, + const QmlJSRefactoringChanges &) { Q_ASSERT(_objectInitializer != 0); @@ -123,9 +124,10 @@ private: changes.insert(currentFile->startOf(_objectInitializer->rbraceToken), QLatin1String("\n")); - currentFile->change(changes); - currentFile->indent(Range(currentFile->startOf(_objectInitializer->lbraceToken), + currentFile->setChangeSet(changes); + currentFile->appendIndentRange(Range(currentFile->startOf(_objectInitializer->lbraceToken), currentFile->startOf(_objectInitializer->rbraceToken))); + currentFile->apply(); } }; }; diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp index 63569ec622..cd19095c7a 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.cpp +++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp @@ -775,11 +775,12 @@ void QmlOutlineModel::reparentNodes(QmlOutlineItem *targetItem, int row, QList<Q } QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), m_semanticInfo.snapshot); - TextEditor::RefactoringFile file = refactoring.file(m_semanticInfo.document->fileName()); - file.change(changeSet); + TextEditor::RefactoringFilePtr file = refactoring.file(m_semanticInfo.document->fileName()); + file->setChangeSet(changeSet); foreach (const Utils::ChangeSet::Range &range, changedRanges) { - file.indent(range); + file->appendIndentRange(range); } + file->apply(); } void QmlOutlineModel::moveObjectMember(AST::UiObjectMember *toMove, diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index b4d1027ed8..0c01f0cea7 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -43,65 +43,82 @@ using namespace QmlJS; using namespace QmlJSTools; +class QmlJSTools::QmlJSRefactoringChangesData : public TextEditor::RefactoringChangesData +{ +public: + QmlJSRefactoringChangesData(ModelManagerInterface *modelManager, + const Snapshot &snapshot) + : m_modelManager(modelManager) + , m_snapshot(snapshot) + {} + + virtual void indentSelection(const QTextCursor &selection, + const QString &fileName, + const TextEditor::BaseTextEditorWidget *textEditor) const + { + // ### shares code with QmlJSTextEditor::indent + QTextDocument *doc = selection.document(); + + QTextBlock block = doc->findBlock(selection.selectionStart()); + const QTextBlock end = doc->findBlock(selection.selectionEnd()).next(); + + const TextEditor::TabSettings &tabSettings = + ProjectExplorer::actualTabSettings(fileName, textEditor); + QtStyleCodeFormatter codeFormatter(tabSettings); + codeFormatter.updateStateUntil(block); + + do { + tabSettings.indentLine(block, codeFormatter.indentFor(block)); + codeFormatter.updateLineStateChange(block); + block = block.next(); + } while (block.isValid() && block != end); + } + + virtual void fileChanged(const QString &fileName) + { + m_modelManager->updateSourceFiles(QStringList(fileName), true); + } + + QmlJS::ModelManagerInterface *m_modelManager; + QmlJS::Snapshot m_snapshot; +}; + QmlJSRefactoringChanges::QmlJSRefactoringChanges(ModelManagerInterface *modelManager, const Snapshot &snapshot) - : m_modelManager(modelManager) - , m_snapshot(snapshot) + : RefactoringChanges(new QmlJSRefactoringChangesData(modelManager, snapshot)) { - Q_ASSERT(modelManager); } -const Snapshot &QmlJSRefactoringChanges::snapshot() const +QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file(const QString &fileName) const { - return m_snapshot; + return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(fileName, m_data)); } -QmlJSRefactoringFile QmlJSRefactoringChanges::file(const QString &fileName) +QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file( + TextEditor::BaseTextEditorWidget *editor, const Document::Ptr &document) { - return QmlJSRefactoringFile(fileName, this); + return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(editor, document)); } -void QmlJSRefactoringChanges::indentSelection(const QTextCursor &selection, - const QString &fileName, - const TextEditor::BaseTextEditorWidget *textEditor) const +const Snapshot &QmlJSRefactoringChanges::snapshot() const { - // ### shares code with QmlJSTextEditor::indent - QTextDocument *doc = selection.document(); - - QTextBlock block = doc->findBlock(selection.selectionStart()); - const QTextBlock end = doc->findBlock(selection.selectionEnd()).next(); - - const TextEditor::TabSettings &tabSettings = - ProjectExplorer::actualTabSettings(fileName, textEditor); - QtStyleCodeFormatter codeFormatter(tabSettings); - codeFormatter.updateStateUntil(block); - - do { - tabSettings.indentLine(block, codeFormatter.indentFor(block)); - codeFormatter.updateLineStateChange(block); - block = block.next(); - } while (block.isValid() && block != end); + return data()->m_snapshot; } -void QmlJSRefactoringChanges::fileChanged(const QString &fileName) +QmlJSRefactoringChangesData *QmlJSRefactoringChanges::data() const { - m_modelManager->updateSourceFiles(QStringList(fileName), true); + return static_cast<QmlJSRefactoringChangesData *>(m_data.data()); } - -QmlJSRefactoringFile::QmlJSRefactoringFile() -{ } - -QmlJSRefactoringFile::QmlJSRefactoringFile(const QString &fileName, QmlJSRefactoringChanges *refactoringChanges) - : RefactoringFile(fileName, refactoringChanges) +QmlJSRefactoringFile::QmlJSRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data) + : RefactoringFile(fileName, data) { } QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document) - : RefactoringFile() + : RefactoringFile(editor) , m_qmljsDocument(document) { m_fileName = document->fileName(); - m_editor = editor; } Document::Ptr QmlJSRefactoringFile::qmljsDocument() const @@ -109,7 +126,7 @@ Document::Ptr QmlJSRefactoringFile::qmljsDocument() const if (!m_qmljsDocument) { const QString source = document()->toPlainText(); const QString name = fileName(); - const Snapshot &snapshot = refactoringChanges()->snapshot(); + const Snapshot &snapshot = data()->m_snapshot; m_qmljsDocument = snapshot.documentFromSource(source, name); m_qmljsDocument->parse(); @@ -145,7 +162,13 @@ bool QmlJSRefactoringFile::isCursorOn(AST::UiQualifiedId *ast) const return pos <= ast->identifierToken.end(); } -QmlJSRefactoringChanges *QmlJSRefactoringFile::refactoringChanges() const +QmlJSRefactoringChangesData *QmlJSRefactoringFile::data() const +{ + return static_cast<QmlJSRefactoringChangesData *>(m_data.data()); +} + +void QmlJSRefactoringFile::fileChanged() { - return static_cast<QmlJSRefactoringChanges *>(m_refactoringChanges); + m_qmljsDocument.clear(); + RefactoringFile::fileChanged(); } diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.h b/src/plugins/qmljstools/qmljsrefactoringchanges.h index c850e10f90..1a9ebe1764 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.h +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.h @@ -46,14 +46,13 @@ class ModelManagerInterface; namespace QmlJSTools { class QmlJSRefactoringChanges; +class QmlJSRefactoringFile; +class QmlJSRefactoringChangesData; +typedef QSharedPointer<QmlJSRefactoringFile> QmlJSRefactoringFilePtr; class QMLJSTOOLS_EXPORT QmlJSRefactoringFile: public TextEditor::RefactoringFile { public: - QmlJSRefactoringFile(); - QmlJSRefactoringFile(const QString &fileName, QmlJSRefactoringChanges *refactoringChanges); - QmlJSRefactoringFile(TextEditor::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document); - QmlJS::Document::Ptr qmljsDocument() const; /*! @@ -65,10 +64,16 @@ public: bool isCursorOn(QmlJS::AST::UiObjectMember *ast) const; bool isCursorOn(QmlJS::AST::UiQualifiedId *ast) const; -private: - QmlJSRefactoringChanges *refactoringChanges() const; +protected: + QmlJSRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data); + QmlJSRefactoringFile(TextEditor::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document); + + QmlJSRefactoringChangesData *data() const; + virtual void fileChanged(); mutable QmlJS::Document::Ptr m_qmljsDocument; + + friend class QmlJSRefactoringChanges; }; @@ -78,19 +83,14 @@ public: QmlJSRefactoringChanges(QmlJS::ModelManagerInterface *modelManager, const QmlJS::Snapshot &snapshot); - const QmlJS::Snapshot &snapshot() const; - - QmlJSRefactoringFile file(const QString &fileName); + static QmlJSRefactoringFilePtr file(TextEditor::BaseTextEditorWidget *editor, + const QmlJS::Document::Ptr &document); + QmlJSRefactoringFilePtr file(const QString &fileName) const; -private: - virtual void indentSelection(const QTextCursor &selection, - const QString &fileName, - const TextEditor::BaseTextEditorWidget *textEditor) const; - virtual void fileChanged(const QString &fileName); + const QmlJS::Snapshot &snapshot() const; private: - QmlJS::ModelManagerInterface *m_modelManager; - QmlJS::Snapshot m_snapshot; + QmlJSRefactoringChangesData *data() const; }; } // namespace QmlJSTools diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index b2d1acb22e..e9ff736358 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -169,7 +169,7 @@ Core::IEditor *BaseTextEditorWidget::openEditorAt(const QString &fileName, int l Core::IEditor *editor = editorManager->openEditor(fileName, editorKind, flags, newEditor); TextEditor::ITextEditor *texteditor = qobject_cast<TextEditor::ITextEditor *>(editor); - if (texteditor) { + if (texteditor && line != -1) { texteditor->gotoLine(line, column); return texteditor; } diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 60d5fb0862..b81ff89494 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -50,17 +50,17 @@ using namespace TextEditor; RefactoringChanges::RefactoringChanges() + : m_data(new RefactoringChangesData) +{} + +RefactoringChanges::RefactoringChanges(RefactoringChangesData *data) + : m_data(data) {} RefactoringChanges::~RefactoringChanges() -{ - if (!m_fileToOpen.isEmpty()) { - BaseTextEditorWidget::openEditorAt(m_fileToOpen, m_lineToOpen, m_columnToOpen); - } -} +{} -BaseTextEditorWidget *RefactoringChanges::editorForFile(const QString &fileName, - bool openIfClosed) +BaseTextEditorWidget *RefactoringChanges::editorForFile(const QString &fileName) { Core::EditorManager *editorManager = Core::EditorManager::instance(); @@ -70,20 +70,7 @@ BaseTextEditorWidget *RefactoringChanges::editorForFile(const QString &fileName, if (textEditor != 0) return textEditor; } - - if (!openIfClosed) - return 0; - - QFile file(fileName); - if (!file.exists()) { - if (!file.open(QIODevice::Append)) - return 0; - file.close(); - } - - Core::IEditor *editor = editorManager->openEditor(fileName, QString(), - Core::EditorManager::NoActivate | Core::EditorManager::IgnoreNavigationHistory); - return qobject_cast<BaseTextEditorWidget *>(editor->widget()); + return 0; } QList<QTextCursor> RefactoringChanges::rangesToSelections(QTextDocument *document, const QList<Range> &ranges) @@ -102,12 +89,15 @@ QList<QTextCursor> RefactoringChanges::rangesToSelections(QTextDocument *documen return selections; } -bool RefactoringChanges::createFile(const QString &fileName, const QString &contents, bool reindent, bool openEditor) +bool RefactoringChanges::createFile(const QString &fileName, const QString &contents, bool reindent, bool openEditor) const { if (QFile::exists(fileName)) return false; - BaseTextEditorWidget *editor = editorForFile(fileName, openEditor); + BaseTextEditorWidget *editor = editorForFile(fileName); + if (!editor && openEditor) { + editor = this->openEditor(fileName, false, -1, -1); + } QTextDocument *document; if (editor) @@ -123,7 +113,7 @@ bool RefactoringChanges::createFile(const QString &fileName, const QString &cont if (reindent) { cursor.select(QTextCursor::Document); - indentSelection(cursor, fileName, editor); + m_data->indentSelection(cursor, fileName, editor); } cursor.endEditBlock(); @@ -137,12 +127,12 @@ bool RefactoringChanges::createFile(const QString &fileName, const QString &cont return false; } - fileChanged(fileName); + m_data->fileChanged(fileName); return true; } -bool RefactoringChanges::removeFile(const QString &fileName) +bool RefactoringChanges::removeFile(const QString &fileName) const { if (!QFile::exists(fileName)) return false; @@ -152,119 +142,70 @@ bool RefactoringChanges::removeFile(const QString &fileName) return true; } -RefactoringFile RefactoringChanges::file(const QString &fileName) +BaseTextEditorWidget *RefactoringChanges::openEditor(const QString &fileName, bool activate, int line, int column) { - if (QFile::exists(fileName)) - return RefactoringFile(fileName, this); - else - return RefactoringFile(); + Core::EditorManager::OpenEditorFlags flags = Core::EditorManager::IgnoreNavigationHistory; + if (!activate) + flags |= Core::EditorManager::NoActivate; + if (line != -1) { + // openEditorAt uses a 1-based line and a 0-based column! + column -= 1; + } + Core::IEditor *editor = BaseTextEditorWidget::openEditorAt( + fileName, line, column, QString(), flags); + return qobject_cast<BaseTextEditorWidget *>(editor->widget()); } -BaseTextEditorWidget *RefactoringChanges::openEditor(const QString &fileName, int pos) +RefactoringFilePtr RefactoringChanges::file(BaseTextEditorWidget *editor) { - BaseTextEditorWidget *editor = editorForFile(fileName, true); - if (pos != -1) { - QTextCursor cursor = editor->textCursor(); - cursor.setPosition(pos); - editor->setTextCursor(cursor); - } - return editor; + return RefactoringFilePtr(new RefactoringFile(editor)); } -void RefactoringChanges::activateEditor(const QString &fileName, int line, int column) +RefactoringFilePtr RefactoringChanges::file(const QString &fileName) const { - m_fileToOpen = fileName; - m_lineToOpen = line; - m_columnToOpen = column; + return RefactoringFilePtr(new RefactoringFile(fileName, m_data)); } - -RefactoringFile::RefactoringFile() - : m_refactoringChanges(0) - , m_document(0) - , m_editor(0) - , m_openEditor(false) -{ } - RefactoringFile::RefactoringFile(QTextDocument *document, const QString &fileName) : m_fileName(fileName) - , m_refactoringChanges(0) , m_document(document) , m_editor(0) , m_openEditor(false) + , m_activateEditor(false) + , m_editorCursorPosition(-1) { } RefactoringFile::RefactoringFile(BaseTextEditorWidget *editor) : m_fileName(editor->file()->fileName()) - , m_refactoringChanges(0) , m_document(0) , m_editor(editor) , m_openEditor(false) + , m_activateEditor(false) + , m_editorCursorPosition(-1) { } -RefactoringFile::RefactoringFile(const QString &fileName, RefactoringChanges *refactoringChanges) +RefactoringFile::RefactoringFile(const QString &fileName, const QSharedPointer<RefactoringChangesData> &data) : m_fileName(fileName) - , m_refactoringChanges(refactoringChanges) + , m_data(data) , m_document(0) , m_editor(0) , m_openEditor(false) + , m_activateEditor(false) + , m_editorCursorPosition(-1) { - m_editor = RefactoringChanges::editorForFile(fileName, false); -} - -RefactoringFile::RefactoringFile(const RefactoringFile &other) - : m_fileName(other.m_fileName) - , m_refactoringChanges(other.m_refactoringChanges) - , m_document(0) - , m_editor(other.m_editor) -{ - Q_ASSERT_X(!other.m_document && other.m_changes.isEmpty() && other.m_indentRanges.isEmpty(), - "RefactoringFile", "A refactoring file with changes is not copyable"); + m_editor = RefactoringChanges::editorForFile(fileName); } RefactoringFile::~RefactoringFile() { - if (m_refactoringChanges && m_openEditor && !m_fileName.isEmpty()) - m_editor = m_refactoringChanges->openEditor(m_fileName, -1); - - // apply changes, if any - if (m_refactoringChanges && !(m_indentRanges.isEmpty() && m_changes.isEmpty())) { - QTextDocument *doc = mutableDocument(); - { - QTextCursor c = cursor(); - c.beginEditBlock(); - - // build indent selections now, applying the changeset will change locations - const QList<QTextCursor> &indentSelections = - RefactoringChanges::rangesToSelections( - doc, m_indentRanges); - - // apply changes and reindent - m_changes.apply(&c); - foreach (const QTextCursor &selection, indentSelections) { - m_refactoringChanges->indentSelection(selection, m_fileName, m_editor); - } - - c.endEditBlock(); - } - - // if this document doesn't have an editor, write the result to a file - if (!m_editor && !m_fileName.isEmpty()) { - Utils::FileSaver saver(m_fileName); - saver.write(doc->toPlainText().toUtf8()); - saver.finalize(Core::ICore::instance()->mainWindow()); - } - - if (!m_fileName.isEmpty()) - m_refactoringChanges->fileChanged(m_fileName); - } - delete m_document; } bool RefactoringFile::isValid() const { - return !m_fileName.isEmpty(); + if (m_fileName.isEmpty()) + return false; + return document(); } const QTextDocument *RefactoringFile::document() const @@ -278,7 +219,7 @@ QTextDocument *RefactoringFile::mutableDocument() const return m_editor->document(); else if (!m_document) { QString fileContents; - if (!m_fileName.isEmpty()) { + if (!m_fileName.isEmpty() && QFile::exists(m_fileName)) { Utils::FileReader reader; if (reader.fetch(m_fileName, Core::ICore::instance()->mainWindow())) fileContents = QString::fromUtf8(reader.data()); @@ -292,8 +233,10 @@ const QTextCursor RefactoringFile::cursor() const { if (m_editor) return m_editor->textCursor(); - else if (!m_fileName.isEmpty()) - return QTextCursor(mutableDocument()); + else if (!m_fileName.isEmpty()) { + if (QTextDocument *doc = mutableDocument()) + return QTextCursor(doc); + } return QTextCursor(); } @@ -312,6 +255,17 @@ int RefactoringFile::position(unsigned line, unsigned column) const return -1; } +void RefactoringFile::lineAndColumn(int offset, unsigned *line, unsigned *column) const +{ + Q_ASSERT(line); + Q_ASSERT(column); + Q_ASSERT(offset >= 0); + QTextCursor c(cursor()); + c.setPosition(offset); + *line = c.blockNumber() + 1; + *column = c.positionInBlock() + 1; +} + QChar RefactoringFile::charAt(int pos) const { if (const QTextDocument *doc = document()) @@ -332,28 +286,87 @@ QString RefactoringFile::textOf(const Range &range) const return textOf(range.start, range.end); } -bool RefactoringFile::change(const Utils::ChangeSet &changeSet, bool openEditor) +void RefactoringFile::setChangeSet(const Utils::ChangeSet &changeSet) { if (m_fileName.isEmpty()) - return false; - if (!m_changes.isEmpty()) - return false; + return; m_changes = changeSet; - m_openEditor = openEditor; - - return true; } -bool RefactoringFile::indent(const Range &range, bool openEditor) +void RefactoringFile::appendIndentRange(const Range &range) { if (m_fileName.isEmpty()) - return false; + return; m_indentRanges.append(range); +} - if (openEditor) - m_openEditor = true; +void RefactoringFile::setOpenEditor(bool activate, int pos) +{ + m_openEditor = true; + m_activateEditor = activate; + m_editorCursorPosition = pos; +} - return true; +void RefactoringFile::apply() +{ + // open / activate / goto position + if (m_openEditor && !m_fileName.isEmpty()) { + unsigned line = -1, column = -1; + if (m_editorCursorPosition != -1) + lineAndColumn(m_editorCursorPosition, &line, &column); + m_editor = RefactoringChanges::openEditor(m_fileName, m_activateEditor, line, column); + m_openEditor = false; + m_activateEditor = false; + m_editorCursorPosition = -1; + } + + // apply changes, if any + if (m_data && !(m_indentRanges.isEmpty() && m_changes.isEmpty())) { + QTextDocument *doc = mutableDocument(); + if (doc) { + QTextCursor c(doc); + c.beginEditBlock(); + + // build indent selections now, applying the changeset will change locations + const QList<QTextCursor> &indentSelections = + RefactoringChanges::rangesToSelections( + doc, m_indentRanges); + m_indentRanges.clear(); + + // apply changes and reindent + m_changes.apply(&c); + m_changes.clear(); + foreach (const QTextCursor &selection, indentSelections) { + m_data->indentSelection(selection, m_fileName, m_editor); + } + + c.endEditBlock(); + } + + // if this document doesn't have an editor, write the result to a file + if (!m_editor && !m_fileName.isEmpty()) { + Utils::FileSaver saver(m_fileName); + saver.write(doc->toPlainText().toUtf8()); + saver.finalize(Core::ICore::instance()->mainWindow()); + } + + fileChanged(); + } +} + +void RefactoringFile::fileChanged() +{ + if (!m_fileName.isEmpty()) + m_data->fileChanged(m_fileName); +} + +void RefactoringChangesData::indentSelection(const QTextCursor &, const QString &, const BaseTextEditorWidget *) const +{ + qWarning() << Q_FUNC_INFO << "not implemented"; +} + +void RefactoringChangesData::fileChanged(const QString &) +{ } diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 4b2bc19764..06c8c1288d 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -38,57 +38,69 @@ #include <QtCore/QList> #include <QtCore/QString> +#include <QtCore/QSharedPointer> -QT_FORWARD_DECLARE_CLASS(QTextDocument) +QT_BEGIN_NAMESPACE +class QTextDocument; +QT_END_NAMESPACE namespace TextEditor { class BaseTextEditorWidget; class RefactoringChanges; +class RefactoringFile; +class RefactoringChangesData; +typedef QSharedPointer<RefactoringFile> RefactoringFilePtr; +// ### listen to the m_editor::destroyed signal? class TEXTEDITOR_EXPORT RefactoringFile { + Q_DISABLE_COPY(RefactoringFile) public: typedef Utils::ChangeSet::Range Range; public: - RefactoringFile(); - // takes ownership of document - RefactoringFile(QTextDocument *document, const QString &fileName = QString()); - RefactoringFile(BaseTextEditorWidget *editor); - RefactoringFile(const RefactoringFile &other); virtual ~RefactoringFile(); bool isValid() const; const QTextDocument *document() const; + // mustn't use the cursor to change the document const QTextCursor cursor() const; QString fileName() const; - // converts 1-based line and column into 0-based offset + // converts 1-based line and column into 0-based source offset int position(unsigned line, unsigned column) const; + // converts 0-based source offset into 1-based line and column + void lineAndColumn(int offset, unsigned *line, unsigned *column) const; QChar charAt(int pos) const; QString textOf(int start, int end) const; QString textOf(const Range &range) const; - bool change(const Utils::ChangeSet &changeSet, bool openEditor = true); - bool indent(const Range &range, bool openEditor = true); + void setChangeSet(const Utils::ChangeSet &changeSet); + void appendIndentRange(const Range &range); + void setOpenEditor(bool activate = false, int pos = -1); + void apply(); protected: - // not assignable - //const RefactoringFile &operator=(const RefactoringFile &other); + RefactoringFile(QTextDocument *document, const QString &fileName); + RefactoringFile(BaseTextEditorWidget *editor); + RefactoringFile(const QString &fileName, const QSharedPointer<RefactoringChangesData> &data); - RefactoringFile(const QString &fileName, RefactoringChanges *refactoringChanges); QTextDocument *mutableDocument() const; + // derived classes may want to clear language specific extra data + virtual void fileChanged(); protected: QString m_fileName; - RefactoringChanges *m_refactoringChanges; + QSharedPointer<RefactoringChangesData> m_data; mutable QTextDocument *m_document; BaseTextEditorWidget *m_editor; Utils::ChangeSet m_changes; QList<Range> m_indentRanges; bool m_openEditor; + bool m_activateEditor; + int m_editorCursorPosition; friend class RefactoringChanges; // access to constructor }; @@ -106,36 +118,37 @@ public: RefactoringChanges(); virtual ~RefactoringChanges(); - bool createFile(const QString &fileName, const QString &contents, bool reindent = true, bool openEditor = true); - bool removeFile(const QString &fileName); + static RefactoringFilePtr file(BaseTextEditorWidget *editor); + RefactoringFilePtr file(const QString &fileName) const; + bool createFile(const QString &fileName, const QString &contents, bool reindent = true, bool openEditor = true) const; + bool removeFile(const QString &fileName) const; - RefactoringFile file(const QString &fileName); + static BaseTextEditorWidget *editorForFile(const QString &fileName); - BaseTextEditorWidget *openEditor(const QString &fileName, int pos = -1); - - /*! - \param fileName the file to activate the editor for - \param line the line to put the cursor on (1-based) - \param column the column to put the cursor on (1-based) - */ - void activateEditor(const QString &fileName, int line, int column); +protected: + explicit RefactoringChanges(RefactoringChangesData *data); - static BaseTextEditorWidget *editorForFile(const QString &fileName, - bool openIfClosed = false); + static BaseTextEditorWidget *openEditor(const QString &fileName, bool activate, int line, int column); -private: static QList<QTextCursor> rangesToSelections(QTextDocument *document, const QList<Range> &ranges); - virtual void indentSelection(const QTextCursor &selection, - const QString &fileName, - const BaseTextEditorWidget *textEditor) const = 0; - virtual void fileChanged(const QString &fileName) = 0; + +protected: + QSharedPointer<RefactoringChangesData> m_data; friend class RefactoringFile; +}; + +class TEXTEDITOR_EXPORT RefactoringChangesData +{ + Q_DISABLE_COPY(RefactoringChangesData) -private: - QString m_fileToOpen; - int m_lineToOpen; - int m_columnToOpen; +public: + RefactoringChangesData() {} + + virtual void indentSelection(const QTextCursor &selection, + const QString &fileName, + const BaseTextEditorWidget *textEditor) const; + virtual void fileChanged(const QString &fileName); }; } // namespace TextEditor |