forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -45,8 +45,8 @@ using namespace CPlusPlus;
|
|||||||
QList<AST *> ASTPath::operator()(int line, int column)
|
QList<AST *> ASTPath::operator()(int line, int column)
|
||||||
{
|
{
|
||||||
_nodes.clear();
|
_nodes.clear();
|
||||||
_line = line + 1;
|
_line = line;
|
||||||
_column = column + 1;
|
_column = column;
|
||||||
|
|
||||||
if (_doc) {
|
if (_doc) {
|
||||||
if (TranslationUnit *unit = _doc->translationUnit())
|
if (TranslationUnit *unit = _doc->translationUnit())
|
||||||
|
@@ -54,9 +54,9 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
QList<AST *> operator()(const QTextCursor &cursor)
|
QList<AST *> operator()(const QTextCursor &cursor)
|
||||||
{ return this->operator()(cursor.blockNumber(), cursor.positionInBlock()); }
|
{ return this->operator()(cursor.blockNumber() + 1, cursor.positionInBlock() + 1); }
|
||||||
|
|
||||||
/// line and column are 0-based!
|
/// line and column are 1-based!
|
||||||
QList<AST *> operator()(int line, int column);
|
QList<AST *> operator()(int line, int column);
|
||||||
|
|
||||||
#ifdef DEBUG_AST_PATH
|
#ifdef DEBUG_AST_PATH
|
||||||
|
@@ -116,15 +116,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile,
|
||||||
|
const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
int start = currentFile->endOf(compoundStatement->lbrace_token);
|
int start = currentFile->endOf(compoundStatement->lbrace_token);
|
||||||
changes.insert(start, QLatin1String("\ncase ")
|
changes.insert(start, QLatin1String("\ncase ")
|
||||||
+ values.join(QLatin1String(":\nbreak;\ncase "))
|
+ values.join(QLatin1String(":\nbreak;\ncase "))
|
||||||
+ QLatin1String(":\nbreak;"));
|
+ QLatin1String(":\nbreak;"));
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(currentFile->range(compoundStatement));
|
currentFile->appendIndentRange(currentFile->range(compoundStatement));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
CompoundStatementAST *compoundStatement;
|
CompoundStatementAST *compoundStatement;
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
#include <cplusplus/TranslationUnit.h>
|
#include <cplusplus/TranslationUnit.h>
|
||||||
#include <cplusplus/LookupContext.h>
|
#include <cplusplus/LookupContext.h>
|
||||||
#include <cplusplus/Overview.h>
|
#include <cplusplus/Overview.h>
|
||||||
|
#include <cpptools/cpprefactoringchanges.h>
|
||||||
#include <texteditor/refactoroverlay.h>
|
#include <texteditor/refactoroverlay.h>
|
||||||
#include <texteditor/tooltip/tooltip.h>
|
#include <texteditor/tooltip/tooltip.h>
|
||||||
#include <texteditor/tooltip/tipcontents.h>
|
#include <texteditor/tooltip/tipcontents.h>
|
||||||
@@ -76,10 +77,11 @@ QTextCursor FunctionDeclDefLinkFinder::scannedSelection() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parent is either a FunctionDefinitionAST or a SimpleDeclarationAST
|
// 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)
|
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
|
// for function definitions, simply scan for FunctionDefinitionAST not preceded
|
||||||
// by CompoundStatement/CtorInitializer
|
// by CompoundStatement/CtorInitializer
|
||||||
@@ -113,19 +115,19 @@ static bool findDeclOrDef(const Document::Ptr &doc, const QTextCursor &cursor,
|
|||||||
return *funcDecl;
|
return *funcDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void declDefLinkStartEnd(const CppTools::CppRefactoringFile &file,
|
static void declDefLinkStartEnd(const CppTools::CppRefactoringFileConstPtr &file,
|
||||||
DeclarationAST *parent, FunctionDeclaratorAST *funcDecl,
|
DeclarationAST *parent, FunctionDeclaratorAST *funcDecl,
|
||||||
int *start, int *end)
|
int *start, int *end)
|
||||||
{
|
{
|
||||||
*start = file.startOf(parent);
|
*start = file->startOf(parent);
|
||||||
if (funcDecl->trailing_return_type)
|
if (funcDecl->trailing_return_type)
|
||||||
*end = file.endOf(funcDecl->trailing_return_type);
|
*end = file->endOf(funcDecl->trailing_return_type);
|
||||||
else if (funcDecl->exception_specification)
|
else if (funcDecl->exception_specification)
|
||||||
*end = file.endOf(funcDecl->exception_specification);
|
*end = file->endOf(funcDecl->exception_specification);
|
||||||
else if (funcDecl->cv_qualifier_list)
|
else if (funcDecl->cv_qualifier_list)
|
||||||
*end = file.endOf(funcDecl->cv_qualifier_list->lastValue());
|
*end = file->endOf(funcDecl->cv_qualifier_list->lastValue());
|
||||||
else
|
else
|
||||||
*end = file.endOf(funcDecl->rparen_token);
|
*end = file->endOf(funcDecl->rparen_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<FunctionDeclDefLink> link, CppTools::CppRefactoringChanges changes)
|
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
|
// parse the target file to get the linked decl/def
|
||||||
const QString targetFileName = QString::fromUtf8(
|
const QString targetFileName = QString::fromUtf8(
|
||||||
target->fileName(), target->fileNameLength());
|
target->fileName(), target->fileNameLength());
|
||||||
CppTools::CppRefactoringFile targetFile = changes.file(targetFileName);
|
CppTools::CppRefactoringFileConstPtr targetFile = changes.fileNoEditor(targetFileName);
|
||||||
if (!targetFile.isValid())
|
if (!targetFile->isValid())
|
||||||
return noResult;
|
return noResult;
|
||||||
|
|
||||||
QTextCursor tc(targetFile.cursor());
|
|
||||||
tc.setPosition(targetFile.position(target->line(), target->column()));
|
|
||||||
DeclarationAST *targetParent = 0;
|
DeclarationAST *targetParent = 0;
|
||||||
FunctionDeclaratorAST *targetFuncDecl = 0;
|
FunctionDeclaratorAST *targetFuncDecl = 0;
|
||||||
if (!findDeclOrDef(targetFile.cppDocument(), tc, &targetParent, &targetFuncDecl))
|
if (!findDeclOrDef(targetFile->cppDocument(), target->line(), target->column(),
|
||||||
|
&targetParent, &targetFuncDecl))
|
||||||
return noResult;
|
return noResult;
|
||||||
|
|
||||||
// the parens are necessary for finding good places for changes
|
// the parens are necessary for finding good places for changes
|
||||||
@@ -169,16 +170,14 @@ static QSharedPointer<FunctionDeclDefLink> findLinkHelper(QSharedPointer<Functio
|
|||||||
|
|
||||||
int targetStart, targetEnd;
|
int targetStart, targetEnd;
|
||||||
declDefLinkStartEnd(targetFile, targetParent, targetFuncDecl, &targetStart, &targetEnd);
|
declDefLinkStartEnd(targetFile, targetParent, targetFuncDecl, &targetStart, &targetEnd);
|
||||||
QString targetInitial = targetFile.textOf(
|
QString targetInitial = targetFile->textOf(
|
||||||
targetFile.startOf(targetParent),
|
targetFile->startOf(targetParent),
|
||||||
targetEnd);
|
targetEnd);
|
||||||
|
|
||||||
link->targetOffset = targetStart;
|
link->targetOffset = targetStart;
|
||||||
link->targetInitial = targetInitial;
|
link->targetInitial = targetInitial;
|
||||||
|
|
||||||
link->targetFile = QSharedPointer<CppTools::CppRefactoringFile>(
|
link->targetFile = targetFile;
|
||||||
new CppTools::CppRefactoringFile(targetFile.document()->clone(), targetFile.fileName()));
|
|
||||||
link->targetFile->setCppDocument(targetFile.cppDocument());
|
|
||||||
link->targetFunction = targetFuncDecl->symbol;
|
link->targetFunction = targetFuncDecl->symbol;
|
||||||
link->targetFunctionDeclarator = targetFuncDecl;
|
link->targetFunctionDeclarator = targetFuncDecl;
|
||||||
link->targetDeclaration = targetParent;
|
link->targetDeclaration = targetParent;
|
||||||
@@ -192,13 +191,13 @@ void FunctionDeclDefLinkFinder::startFindLinkAt(
|
|||||||
// check if cursor is on function decl/def
|
// check if cursor is on function decl/def
|
||||||
DeclarationAST *parent = 0;
|
DeclarationAST *parent = 0;
|
||||||
FunctionDeclaratorAST *funcDecl = 0;
|
FunctionDeclaratorAST *funcDecl = 0;
|
||||||
if (!findDeclOrDef(doc, cursor, &parent, &funcDecl))
|
if (!findDeclOrDef(doc, cursor.blockNumber() + 1, cursor.columnNumber() + 1, &parent, &funcDecl))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// find the start/end offsets
|
// find the start/end offsets
|
||||||
CppTools::CppRefactoringChanges refactoringChanges(snapshot);
|
CppTools::CppRefactoringChanges refactoringChanges(snapshot);
|
||||||
CppTools::CppRefactoringFile sourceFile = refactoringChanges.file(doc->fileName());
|
CppTools::CppRefactoringFilePtr sourceFile = refactoringChanges.file(doc->fileName());
|
||||||
sourceFile.setCppDocument(doc);
|
sourceFile->setCppDocument(doc);
|
||||||
int start, end;
|
int start, end;
|
||||||
declDefLinkStartEnd(sourceFile, parent, funcDecl, &start, &end);
|
declDefLinkStartEnd(sourceFile, parent, funcDecl, &start, &end);
|
||||||
|
|
||||||
@@ -242,7 +241,7 @@ FunctionDeclDefLink::~FunctionDeclDefLink()
|
|||||||
|
|
||||||
bool FunctionDeclDefLink::isValid() const
|
bool FunctionDeclDefLink::isValid() const
|
||||||
{
|
{
|
||||||
return targetFile;
|
return !linkSelection.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionDeclDefLink::isMarkerVisible() const
|
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
|
// first verify the interesting region of the target file is unchanged
|
||||||
CppTools::CppRefactoringChanges refactoringChanges(snapshot);
|
CppTools::CppRefactoringChanges refactoringChanges(snapshot);
|
||||||
CppTools::CppRefactoringFile newTargetFile = refactoringChanges.file(targetFile->fileName());
|
CppTools::CppRefactoringFilePtr newTargetFile = refactoringChanges.file(targetFile->fileName());
|
||||||
if (!newTargetFile.isValid())
|
if (!newTargetFile->isValid())
|
||||||
return;
|
return;
|
||||||
const int targetEnd = targetOffset + targetInitial.size();
|
const int targetEnd = targetOffset + targetInitial.size();
|
||||||
if (targetInitial == newTargetFile.textOf(targetOffset, targetEnd)) {
|
if (targetInitial == newTargetFile->textOf(targetOffset, targetEnd)) {
|
||||||
const Utils::ChangeSet changeset = changes(snapshot);
|
const Utils::ChangeSet changeset = changes(snapshot);
|
||||||
newTargetFile.change(changeset, jumpToMatch);
|
newTargetFile->setChangeSet(changeset);
|
||||||
if (jumpToMatch) {
|
if (jumpToMatch)
|
||||||
QTextCursor tc = newTargetFile.cursor();
|
newTargetFile->setOpenEditor(true, targetOffset);
|
||||||
tc.setPosition(targetOffset + targetInitial.size());
|
newTargetFile->apply();
|
||||||
refactoringChanges.activateEditor(newTargetFile.fileName(), tc.blockNumber(), tc.columnNumber());
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
TextEditor::ToolTip::instance()->show(
|
TextEditor::ToolTip::instance()->show(
|
||||||
editor->toolTipPosition(linkSelection),
|
editor->toolTipPosition(linkSelection),
|
||||||
@@ -361,8 +358,6 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot)
|
|||||||
{
|
{
|
||||||
Utils::ChangeSet changes;
|
Utils::ChangeSet changes;
|
||||||
|
|
||||||
QSharedPointer<CppTools::CppRefactoringFile> matchFile = targetFile;
|
|
||||||
|
|
||||||
// parse the current source declaration
|
// parse the current source declaration
|
||||||
TypeOfExpression typeOfExpression; // ### just need to preprocess...
|
TypeOfExpression typeOfExpression; // ### just need to preprocess...
|
||||||
typeOfExpression.init(sourceDocument, snapshot);
|
typeOfExpression.init(sourceDocument, snapshot);
|
||||||
@@ -412,15 +407,15 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot)
|
|||||||
if (SimpleDeclarationAST *simple = targetDeclaration->asSimpleDeclaration()) {
|
if (SimpleDeclarationAST *simple = targetDeclaration->asSimpleDeclaration()) {
|
||||||
declarator = simple->declarator_list->value;
|
declarator = simple->declarator_list->value;
|
||||||
if (simple->decl_specifier_list)
|
if (simple->decl_specifier_list)
|
||||||
returnTypeStart = matchFile->startOf(simple->decl_specifier_list->value);
|
returnTypeStart = targetFile->startOf(simple->decl_specifier_list->value);
|
||||||
else
|
else
|
||||||
returnTypeStart = matchFile->startOf(declarator);
|
returnTypeStart = targetFile->startOf(declarator);
|
||||||
} else if (FunctionDefinitionAST *def = targetDeclaration->asFunctionDefinition()) {
|
} else if (FunctionDefinitionAST *def = targetDeclaration->asFunctionDefinition()) {
|
||||||
declarator = def->declarator;
|
declarator = def->declarator;
|
||||||
if (def->decl_specifier_list)
|
if (def->decl_specifier_list)
|
||||||
returnTypeStart = matchFile->startOf(def->decl_specifier_list->value);
|
returnTypeStart = targetFile->startOf(def->decl_specifier_list->value);
|
||||||
else
|
else
|
||||||
returnTypeStart = matchFile->startOf(declarator);
|
returnTypeStart = targetFile->startOf(declarator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newFunction->returnType().isEqualTo(sourceFunction->returnType())
|
if (!newFunction->returnType().isEqualTo(sourceFunction->returnType())
|
||||||
@@ -428,7 +423,7 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot)
|
|||||||
FullySpecifiedType type = rewriteType(newFunction->returnType(), &env, control);
|
FullySpecifiedType type = rewriteType(newFunction->returnType(), &env, control);
|
||||||
const QString replacement = overview(type, targetFunction->name());
|
const QString replacement = overview(type, targetFunction->name());
|
||||||
changes.replace(returnTypeStart,
|
changes.replace(returnTypeStart,
|
||||||
matchFile->startOf(targetFunctionDeclarator->lparen_token),
|
targetFile->startOf(targetFunctionDeclarator->lparen_token),
|
||||||
replacement);
|
replacement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,35 +473,35 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot)
|
|||||||
ParameterDeclarationAST *targetParamAst = targetParameterDeclIt->value;
|
ParameterDeclarationAST *targetParamAst = targetParameterDeclIt->value;
|
||||||
int parameterNameEnd = 0;
|
int parameterNameEnd = 0;
|
||||||
if (targetParamAst->declarator)
|
if (targetParamAst->declarator)
|
||||||
parameterNameEnd = matchFile->endOf(targetParamAst->declarator);
|
parameterNameEnd = targetFile->endOf(targetParamAst->declarator);
|
||||||
else if (targetParamAst->type_specifier_list)
|
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
|
else
|
||||||
parameterNameEnd = matchFile->startOf(targetParamAst);
|
parameterNameEnd = targetFile->startOf(targetParamAst);
|
||||||
|
|
||||||
if (allowChangeType
|
if (allowChangeType
|
||||||
&& !targetParam->type().isEqualTo(newParam->type())) {
|
&& !targetParam->type().isEqualTo(newParam->type())) {
|
||||||
FullySpecifiedType replacementType = rewriteType(newParam->type(), &env, control);
|
FullySpecifiedType replacementType = rewriteType(newParam->type(), &env, control);
|
||||||
const QString replacement = overview(replacementType, replacementName);
|
const QString replacement = overview(replacementType, replacementName);
|
||||||
|
|
||||||
changes.replace(matchFile->startOf(targetParamAst),
|
changes.replace(targetFile->startOf(targetParamAst),
|
||||||
parameterNameEnd,
|
parameterNameEnd,
|
||||||
replacement);
|
replacement);
|
||||||
} else if (!namesEqual(targetParam->name(), replacementName)) {
|
} else if (!namesEqual(targetParam->name(), replacementName)) {
|
||||||
DeclaratorIdAST *id = getDeclaratorId(targetParamAst->declarator);
|
DeclaratorIdAST *id = getDeclaratorId(targetParamAst->declarator);
|
||||||
QString replacementNameStr = overview(replacementName);
|
QString replacementNameStr = overview(replacementName);
|
||||||
if (id) {
|
if (id) {
|
||||||
changes.replace(matchFile->range(id), replacementNameStr);
|
changes.replace(targetFile->range(id), replacementNameStr);
|
||||||
} else {
|
} else {
|
||||||
// add name to unnamed parameter
|
// add name to unnamed parameter
|
||||||
replacementNameStr.prepend(QLatin1Char(' '));
|
replacementNameStr.prepend(QLatin1Char(' '));
|
||||||
int end;
|
int end;
|
||||||
if (targetParamAst->equal_token) {
|
if (targetParamAst->equal_token) {
|
||||||
end = matchFile->startOf(targetParamAst->equal_token);
|
end = targetFile->startOf(targetParamAst->equal_token);
|
||||||
replacementNameStr.append(QLatin1Char(' '));
|
replacementNameStr.append(QLatin1Char(' '));
|
||||||
} else {
|
} else {
|
||||||
// one past end on purpose
|
// one past end on purpose
|
||||||
end = matchFile->startOf(targetParamAst->lastToken());
|
end = targetFile->startOf(targetParamAst->lastToken());
|
||||||
}
|
}
|
||||||
changes.replace(parameterNameEnd, end, replacementNameStr);
|
changes.replace(parameterNameEnd, end, replacementNameStr);
|
||||||
}
|
}
|
||||||
@@ -516,15 +511,15 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot)
|
|||||||
targetParameterDeclIt = firstTargetParameterDeclIt;
|
targetParameterDeclIt = firstTargetParameterDeclIt;
|
||||||
if (targetParameterDeclIt) {
|
if (targetParameterDeclIt) {
|
||||||
if (newArgCount == 0) {
|
if (newArgCount == 0) {
|
||||||
changes.remove(matchFile->startOf(targetParameterDeclIt->firstToken()),
|
changes.remove(targetFile->startOf(targetParameterDeclIt->firstToken()),
|
||||||
matchFile->endOf(targetParameterDeclIt->lastToken() - 1));
|
targetFile->endOf(targetParameterDeclIt->lastToken() - 1));
|
||||||
} else {
|
} else {
|
||||||
// get the last valid argument
|
// get the last valid argument
|
||||||
for (unsigned i = 0; i < newArgCount - 1 && targetParameterDeclIt; ++i)
|
for (unsigned i = 0; i < newArgCount - 1 && targetParameterDeclIt; ++i)
|
||||||
targetParameterDeclIt = targetParameterDeclIt->next;
|
targetParameterDeclIt = targetParameterDeclIt->next;
|
||||||
if (targetParameterDeclIt) {
|
if (targetParameterDeclIt) {
|
||||||
const int start = matchFile->endOf(targetParameterDeclIt->value);
|
const int start = targetFile->endOf(targetParameterDeclIt->value);
|
||||||
const int end = matchFile->endOf(targetParameterDecl->lastToken() - 1);
|
const int end = targetFile->endOf(targetParameterDecl->lastToken() - 1);
|
||||||
changes.remove(start, end);
|
changes.remove(start, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -542,9 +537,9 @@ Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot)
|
|||||||
if (targetParameterDeclIt) {
|
if (targetParameterDeclIt) {
|
||||||
while (targetParameterDeclIt->next)
|
while (targetParameterDeclIt->next)
|
||||||
targetParameterDeclIt = targetParameterDeclIt->next;
|
targetParameterDeclIt = targetParameterDeclIt->next;
|
||||||
changes.insert(matchFile->endOf(targetParameterDeclIt->value), newParams);
|
changes.insert(targetFile->endOf(targetParameterDeclIt->value), newParams);
|
||||||
} else {
|
} 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 += QLatin1Char(' ');
|
||||||
cvString += QLatin1String("volatile");
|
cvString += QLatin1String("volatile");
|
||||||
}
|
}
|
||||||
const int rparenEnd = matchFile->endOf(targetFunctionDeclarator->rparen_token);
|
const int rparenEnd = targetFile->endOf(targetFunctionDeclarator->rparen_token);
|
||||||
if (targetFunctionDeclarator->cv_qualifier_list) {
|
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 the qualifies changed, replace
|
||||||
if (!cvString.isEmpty()) {
|
if (!cvString.isEmpty()) {
|
||||||
changes.replace(matchFile->startOf(targetFunctionDeclarator->cv_qualifier_list->firstToken()),
|
changes.replace(targetFile->startOf(targetFunctionDeclarator->cv_qualifier_list->firstToken()),
|
||||||
cvEnd, cvString);
|
cvEnd, cvString);
|
||||||
} else {
|
} else {
|
||||||
// remove
|
// remove
|
||||||
|
@@ -100,7 +100,7 @@ public:
|
|||||||
CPlusPlus::DeclarationAST *sourceDeclaration;
|
CPlusPlus::DeclarationAST *sourceDeclaration;
|
||||||
CPlusPlus::FunctionDeclaratorAST *sourceFunctionDeclarator;
|
CPlusPlus::FunctionDeclaratorAST *sourceFunctionDeclarator;
|
||||||
|
|
||||||
QSharedPointer<CppTools::CppRefactoringFile> targetFile;
|
CppTools::CppRefactoringFileConstPtr targetFile;
|
||||||
CPlusPlus::Function *targetFunction;
|
CPlusPlus::Function *targetFunction;
|
||||||
CPlusPlus::DeclarationAST *targetDeclaration;
|
CPlusPlus::DeclarationAST *targetDeclaration;
|
||||||
CPlusPlus::FunctionDeclaratorAST *targetFunctionDeclarator;
|
CPlusPlus::FunctionDeclaratorAST *targetFunctionDeclarator;
|
||||||
|
@@ -80,25 +80,24 @@ public:
|
|||||||
"Add %1 Declaration").arg(type));
|
"Add %1 Declaration").arg(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void performChanges(CppRefactoringFile *, CppRefactoringChanges *refactoring)
|
void performChanges(const CppRefactoringFilePtr &,
|
||||||
|
const CppRefactoringChanges &refactoring)
|
||||||
{
|
{
|
||||||
InsertionPointLocator locator(refactoring);
|
InsertionPointLocator locator(refactoring);
|
||||||
const InsertionLocation loc = locator.methodDeclarationInClass(
|
const InsertionLocation loc = locator.methodDeclarationInClass(
|
||||||
m_targetFileName, m_targetSymbol, m_xsSpec);
|
m_targetFileName, m_targetSymbol, m_xsSpec);
|
||||||
Q_ASSERT(loc.isValid());
|
Q_ASSERT(loc.isValid());
|
||||||
|
|
||||||
CppRefactoringFile targetFile = refactoring->file(m_targetFileName);
|
CppRefactoringFilePtr targetFile = refactoring.file(m_targetFileName);
|
||||||
int targetPosition1 = targetFile.position(loc.line(), loc.column());
|
int targetPosition1 = targetFile->position(loc.line(), loc.column());
|
||||||
int targetPosition2 = qMax(0, targetFile.position(loc.line(), 1) - 1);
|
int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1);
|
||||||
|
|
||||||
Utils::ChangeSet target;
|
Utils::ChangeSet target;
|
||||||
target.insert(targetPosition1, loc.prefix() + m_decl);
|
target.insert(targetPosition1, loc.prefix() + m_decl);
|
||||||
targetFile.change(target);
|
targetFile->setChangeSet(target);
|
||||||
targetFile.indent(Utils::ChangeSet::Range(targetPosition2, targetPosition1));
|
targetFile->appendIndentRange(Utils::ChangeSet::Range(targetPosition2, targetPosition1));
|
||||||
|
targetFile->setOpenEditor(true, targetPosition1);
|
||||||
const int prefixLineCount = loc.prefix().count(QLatin1Char('\n'));
|
targetFile->apply();
|
||||||
refactoring->activateEditor(m_targetFileName, loc.line() + prefixLineCount,
|
|
||||||
qMax(((int) loc.column()) - 1, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -114,7 +113,7 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match(
|
|||||||
const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface)
|
const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface)
|
||||||
{
|
{
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
FunctionDefinitionAST *funDef = 0;
|
FunctionDefinitionAST *funDef = 0;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
@@ -122,7 +121,7 @@ QList<CppQuickFixOperation::Ptr> DeclFromDef::match(
|
|||||||
AST *node = path.at(idx);
|
AST *node = path.at(idx);
|
||||||
if (idx > 1) {
|
if (idx > 1) {
|
||||||
if (DeclaratorIdAST *declId = node->asDeclaratorId()) {
|
if (DeclaratorIdAST *declId = node->asDeclaratorId()) {
|
||||||
if (file.isCursorOn(declId)) {
|
if (file->isCursorOn(declId)) {
|
||||||
if (FunctionDefinitionAST *candidate = path.at(idx - 2)->asFunctionDefinition()) {
|
if (FunctionDefinitionAST *candidate = path.at(idx - 2)->asFunctionDefinition()) {
|
||||||
if (funDef) {
|
if (funDef) {
|
||||||
return noResult();
|
return noResult();
|
||||||
@@ -230,12 +229,12 @@ public:
|
|||||||
.arg(dir.relativeFilePath(m_loc.fileName())));
|
.arg(dir.relativeFilePath(m_loc.fileName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
void performChanges(CppRefactoringFile *,
|
void performChanges(const CppRefactoringFilePtr &,
|
||||||
CppRefactoringChanges *refactoring)
|
const CppRefactoringChanges &refactoring)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_loc.isValid());
|
Q_ASSERT(m_loc.isValid());
|
||||||
|
|
||||||
CppRefactoringFile targetFile = refactoring->file(m_loc.fileName());
|
CppRefactoringFilePtr targetFile = refactoring.file(m_loc.fileName());
|
||||||
|
|
||||||
Overview oo;
|
Overview oo;
|
||||||
oo.setShowFunctionSignatures(true);
|
oo.setShowFunctionSignatures(true);
|
||||||
@@ -243,7 +242,7 @@ public:
|
|||||||
oo.setShowArgumentNames(true);
|
oo.setShowArgumentNames(true);
|
||||||
|
|
||||||
// make target lookup context
|
// make target lookup context
|
||||||
Document::Ptr targetDoc = targetFile.cppDocument();
|
Document::Ptr targetDoc = targetFile->cppDocument();
|
||||||
Scope *targetScope = targetDoc->scopeAt(m_loc.line(), m_loc.column());
|
Scope *targetScope = targetDoc->scopeAt(m_loc.line(), m_loc.column());
|
||||||
LookupContext targetContext(targetDoc, assistInterface()->snapshot());
|
LookupContext targetContext(targetDoc, assistInterface()->snapshot());
|
||||||
ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
|
ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
|
||||||
@@ -272,18 +271,15 @@ public:
|
|||||||
|
|
||||||
QString defText = oo.prettyType(tn, name) + "\n{\n}";
|
QString defText = oo.prettyType(tn, name) + "\n{\n}";
|
||||||
|
|
||||||
int targetPos = targetFile.position(m_loc.line(), m_loc.column());
|
int targetPos = targetFile->position(m_loc.line(), m_loc.column());
|
||||||
int targetPos2 = qMax(0, targetFile.position(m_loc.line(), 1) - 1);
|
int targetPos2 = qMax(0, targetFile->position(m_loc.line(), 1) - 1);
|
||||||
|
|
||||||
Utils::ChangeSet target;
|
Utils::ChangeSet target;
|
||||||
target.insert(targetPos, m_loc.prefix() + defText + m_loc.suffix());
|
target.insert(targetPos, m_loc.prefix() + defText + m_loc.suffix());
|
||||||
targetFile.change(target);
|
targetFile->setChangeSet(target);
|
||||||
targetFile.indent(Utils::ChangeSet::Range(targetPos2, targetPos));
|
targetFile->appendIndentRange(Utils::ChangeSet::Range(targetPos2, targetPos));
|
||||||
|
targetFile->setOpenEditor(true, targetPos);
|
||||||
const int prefixLineCount = m_loc.prefix().count(QLatin1Char('\n'));
|
targetFile->apply();
|
||||||
refactoring->activateEditor(m_loc.fileName(),
|
|
||||||
m_loc.line() + prefixLineCount,
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -297,7 +293,7 @@ QList<CppQuickFixOperation::Ptr> DefFromDecl::match(
|
|||||||
const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface)
|
const QSharedPointer<const Internal::CppQuickFixAssistInterface> &interface)
|
||||||
{
|
{
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
int idx = path.size() - 1;
|
int idx = path.size() - 1;
|
||||||
for (; idx >= 0; --idx) {
|
for (; idx >= 0; --idx) {
|
||||||
@@ -311,9 +307,9 @@ QList<CppQuickFixOperation::Ptr> DefFromDecl::match(
|
|||||||
&& decl->enclosingScope()
|
&& decl->enclosingScope()
|
||||||
&& decl->enclosingScope()->isClass()) {
|
&& decl->enclosingScope()->isClass()) {
|
||||||
DeclaratorAST *declarator = simpleDecl->declarator_list->value;
|
DeclaratorAST *declarator = simpleDecl->declarator_list->value;
|
||||||
if (file.isCursorOn(declarator->core_declarator)) {
|
if (file->isCursorOn(declarator->core_declarator)) {
|
||||||
CppRefactoringChanges refactoring(interface->snapshot());
|
CppRefactoringChanges refactoring(interface->snapshot());
|
||||||
InsertionPointLocator locator(&refactoring);
|
InsertionPointLocator locator(refactoring);
|
||||||
QList<CppQuickFixOperation::Ptr> results;
|
QList<CppQuickFixOperation::Ptr> results;
|
||||||
foreach (const InsertionLocation &loc, locator.methodDefinition(decl)) {
|
foreach (const InsertionLocation &loc, locator.methodDefinition(decl)) {
|
||||||
if (loc.isValid())
|
if (loc.isValid())
|
||||||
|
@@ -71,24 +71,23 @@ QList<CppQuickFixOperation::Ptr> InsertQtPropertyMembers::match(
|
|||||||
if (!klass)
|
if (!klass)
|
||||||
return noResult();
|
return noResult();
|
||||||
|
|
||||||
CppRefactoringChanges refactoring(interface->snapshot());
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
const CppRefactoringFile &file = refactoring.file(interface->file()->fileName());
|
const QString propertyName = file->textOf(qtPropertyDeclaration->property_name);
|
||||||
const QString propertyName = file.textOf(qtPropertyDeclaration->property_name);
|
|
||||||
QString getterName;
|
QString getterName;
|
||||||
QString setterName;
|
QString setterName;
|
||||||
QString signalName;
|
QString signalName;
|
||||||
int generateFlags = 0;
|
int generateFlags = 0;
|
||||||
for (QtPropertyDeclarationItemListAST *it = qtPropertyDeclaration->property_declaration_item_list;
|
for (QtPropertyDeclarationItemListAST *it = qtPropertyDeclaration->property_declaration_item_list;
|
||||||
it; it = it->next) {
|
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")) {
|
if (tokenString == QLatin1String("READ")) {
|
||||||
getterName = file.textOf(it->value->expression);
|
getterName = file->textOf(it->value->expression);
|
||||||
generateFlags |= GenerateGetter;
|
generateFlags |= GenerateGetter;
|
||||||
} else if (tokenString == QLatin1String("WRITE")) {
|
} else if (tokenString == QLatin1String("WRITE")) {
|
||||||
setterName = file.textOf(it->value->expression);
|
setterName = file->textOf(it->value->expression);
|
||||||
generateFlags |= GenerateSetter;
|
generateFlags |= GenerateSetter;
|
||||||
} else if (tokenString == QLatin1String("NOTIFY")) {
|
} else if (tokenString == QLatin1String("NOTIFY")) {
|
||||||
signalName = file.textOf(it->value->expression);
|
signalName = file->textOf(it->value->expression);
|
||||||
generateFlags |= GenerateSignal;
|
generateFlags |= GenerateSignal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,7 +142,8 @@ InsertQtPropertyMembers::Operation::Operation(
|
|||||||
setDescription(desc);
|
setDescription(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertQtPropertyMembers::Operation::performChanges(CppRefactoringFile *file, CppRefactoringChanges *refactoring)
|
void InsertQtPropertyMembers::Operation::performChanges(const CppRefactoringFilePtr &file,
|
||||||
|
const CppRefactoringChanges &refactoring)
|
||||||
{
|
{
|
||||||
InsertionPointLocator locator(refactoring);
|
InsertionPointLocator locator(refactoring);
|
||||||
Utils::ChangeSet declarations;
|
Utils::ChangeSet declarations;
|
||||||
@@ -190,13 +190,14 @@ void InsertQtPropertyMembers::Operation::performChanges(CppRefactoringFile *file
|
|||||||
insertAndIndent(file, &declarations, storageLoc, storageDeclaration);
|
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 targetPosition1 = file->position(loc.line(), loc.column());
|
||||||
int targetPosition2 = qMax(0, file->position(loc.line(), 1) - 1);
|
int targetPosition2 = qMax(0, file->position(loc.line(), 1) - 1);
|
||||||
changeSet->insert(targetPosition1, loc.prefix() + text + loc.suffix());
|
changeSet->insert(targetPosition1, loc.prefix() + text + loc.suffix());
|
||||||
file->indent(Utils::ChangeSet::Range(targetPosition2, targetPosition1));
|
file->appendIndentRange(Utils::ChangeSet::Range(targetPosition2, targetPosition1));
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,7 @@ class Class;
|
|||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
class RefactoringFile;
|
class RefactoringFile;
|
||||||
|
typedef QSharedPointer<RefactoringFile> RefactoringFilePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -83,11 +84,11 @@ private:
|
|||||||
const QString &getterName, const QString &setterName, const QString &signalName,
|
const QString &getterName, const QString &setterName, const QString &signalName,
|
||||||
const QString &storageName);
|
const QString &storageName);
|
||||||
|
|
||||||
virtual void performChanges(CppTools::CppRefactoringFile *file,
|
virtual void performChanges(const CppTools::CppRefactoringFilePtr &file,
|
||||||
CppTools::CppRefactoringChanges *refactoring);
|
const CppTools::CppRefactoringChanges &refactoring);
|
||||||
|
|
||||||
private:
|
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);
|
const CppTools::InsertionLocation &loc, const QString &text);
|
||||||
|
|
||||||
CPlusPlus::QtPropertyDeclarationAST *m_declaration;
|
CPlusPlus::QtPropertyDeclarationAST *m_declaration;
|
||||||
|
@@ -70,9 +70,9 @@ CppQuickFixOperation::~CppQuickFixOperation()
|
|||||||
void CppQuickFixOperation::perform()
|
void CppQuickFixOperation::perform()
|
||||||
{
|
{
|
||||||
CppRefactoringChanges refactoring(m_interface->snapshot());
|
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
|
const CppQuickFixAssistInterface *CppQuickFixOperation::assistInterface() const
|
||||||
|
@@ -40,6 +40,7 @@ namespace CppTools {
|
|||||||
class CppModelManagerInterface;
|
class CppModelManagerInterface;
|
||||||
class CppRefactoringFile;
|
class CppRefactoringFile;
|
||||||
class CppRefactoringChanges;
|
class CppRefactoringChanges;
|
||||||
|
typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr;
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
|
||||||
namespace ExtensionSystem {
|
namespace ExtensionSystem {
|
||||||
@@ -63,8 +64,8 @@ public:
|
|||||||
virtual void perform();
|
virtual void perform();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void performChanges(CppTools::CppRefactoringFile *currentFile,
|
virtual void performChanges(const CppTools::CppRefactoringFilePtr ¤tFile,
|
||||||
CppTools::CppRefactoringChanges *refactoring) = 0;
|
const CppTools::CppRefactoringChanges &refactoring) = 0;
|
||||||
|
|
||||||
QString fileName() const;
|
QString fileName() const;
|
||||||
|
|
||||||
|
@@ -105,6 +105,7 @@ CppQuickFixAssistInterface::CppQuickFixAssistInterface(CPPEditorWidget *editor,
|
|||||||
, m_editor(editor)
|
, m_editor(editor)
|
||||||
, m_semanticInfo(editor->semanticInfo())
|
, m_semanticInfo(editor->semanticInfo())
|
||||||
, m_snapshot(CPlusPlus::CppModelManagerInterface::instance()->snapshot())
|
, m_snapshot(CPlusPlus::CppModelManagerInterface::instance()->snapshot())
|
||||||
|
, m_currentFile(CppRefactoringChanges::file(editor, m_semanticInfo.doc))
|
||||||
, m_context(m_semanticInfo.doc, m_snapshot)
|
, m_context(m_semanticInfo.doc, m_snapshot)
|
||||||
{
|
{
|
||||||
CPlusPlus::ASTPath astPath(m_semanticInfo.doc);
|
CPlusPlus::ASTPath astPath(m_semanticInfo.doc);
|
||||||
@@ -136,19 +137,17 @@ CPPEditorWidget *CppQuickFixAssistInterface::editor() const
|
|||||||
return m_editor;
|
return m_editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CppRefactoringFile CppQuickFixAssistInterface::currentFile() const
|
CppRefactoringFilePtr CppQuickFixAssistInterface::currentFile() const
|
||||||
{
|
{
|
||||||
CppRefactoringFile file(m_editor);
|
return m_currentFile;
|
||||||
file.setCppDocument(m_semanticInfo.doc);
|
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppQuickFixAssistInterface::isCursorOn(unsigned tokenIndex) const
|
bool CppQuickFixAssistInterface::isCursorOn(unsigned tokenIndex) const
|
||||||
{
|
{
|
||||||
return currentFile().isCursorOn(tokenIndex);
|
return currentFile()->isCursorOn(tokenIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppQuickFixAssistInterface::isCursorOn(const CPlusPlus::AST *ast) const
|
bool CppQuickFixAssistInterface::isCursorOn(const CPlusPlus::AST *ast) const
|
||||||
{
|
{
|
||||||
return currentFile().isCursorOn(ast);
|
return currentFile()->isCursorOn(ast);
|
||||||
}
|
}
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
class CppRefactoringFile;
|
class CppRefactoringFile;
|
||||||
|
typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace CppEditor {
|
namespace CppEditor {
|
||||||
@@ -62,7 +63,7 @@ public:
|
|||||||
const CPlusPlus::LookupContext &context() const;
|
const CPlusPlus::LookupContext &context() const;
|
||||||
CPPEditorWidget *editor() const;
|
CPPEditorWidget *editor() const;
|
||||||
|
|
||||||
const CppTools::CppRefactoringFile currentFile() const;
|
CppTools::CppRefactoringFilePtr currentFile() const;
|
||||||
|
|
||||||
bool isCursorOn(unsigned tokenIndex) const;
|
bool isCursorOn(unsigned tokenIndex) const;
|
||||||
bool isCursorOn(const CPlusPlus::AST *ast) const;
|
bool isCursorOn(const CPlusPlus::AST *ast) const;
|
||||||
@@ -71,6 +72,7 @@ private:
|
|||||||
CPPEditorWidget *m_editor;
|
CPPEditorWidget *m_editor;
|
||||||
CppEditor::Internal::SemanticInfo m_semanticInfo;
|
CppEditor::Internal::SemanticInfo m_semanticInfo;
|
||||||
CPlusPlus::Snapshot m_snapshot;
|
CPlusPlus::Snapshot m_snapshot;
|
||||||
|
CppTools::CppRefactoringFilePtr m_currentFile;
|
||||||
CPlusPlus::LookupContext m_context;
|
CPlusPlus::LookupContext m_context;
|
||||||
QList<CPlusPlus::AST *> m_path;
|
QList<CPlusPlus::AST *> m_path;
|
||||||
};
|
};
|
||||||
|
@@ -89,7 +89,7 @@ public:
|
|||||||
virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface)
|
virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface)
|
||||||
{
|
{
|
||||||
QList<CppQuickFixOperation::Ptr> result;
|
QList<CppQuickFixOperation::Ptr> result;
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
int index = path.size() - 1;
|
int index = path.size() - 1;
|
||||||
@@ -100,7 +100,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
Kind invertToken;
|
Kind invertToken;
|
||||||
switch (file.tokenAt(binary->binary_op_token).kind()) {
|
switch (file->tokenAt(binary->binary_op_token).kind()) {
|
||||||
case T_LESS_EQUAL:
|
case T_LESS_EQUAL:
|
||||||
invertToken = T_GREATER;
|
invertToken = T_GREATER;
|
||||||
break;
|
break;
|
||||||
@@ -153,7 +153,7 @@ private:
|
|||||||
// check for ! before parentheses
|
// check for ! before parentheses
|
||||||
if (nested && priority - 2 >= 0) {
|
if (nested && priority - 2 >= 0) {
|
||||||
negation = interface->path()[priority - 2]->asUnaryExpression();
|
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;
|
negation = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ private:
|
|||||||
return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement);
|
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;
|
ChangeSet changes;
|
||||||
if (negation) {
|
if (negation) {
|
||||||
@@ -176,7 +176,8 @@ private:
|
|||||||
changes.insert(currentFile->endOf(binary), ")");
|
changes.insert(currentFile->endOf(binary), ")");
|
||||||
}
|
}
|
||||||
changes.replace(currentFile->range(binary->binary_op_token), replacement);
|
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;
|
QList<QuickFixOperation::Ptr> result;
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
int index = path.size() - 1;
|
int index = path.size() - 1;
|
||||||
BinaryExpressionAST *binary = path.at(index)->asBinaryExpression();
|
BinaryExpressionAST *binary = path.at(index)->asBinaryExpression();
|
||||||
@@ -207,7 +208,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
Kind flipToken;
|
Kind flipToken;
|
||||||
switch (file.tokenAt(binary->binary_op_token).kind()) {
|
switch (file->tokenAt(binary->binary_op_token).kind()) {
|
||||||
case T_LESS_EQUAL:
|
case T_LESS_EQUAL:
|
||||||
flipToken = T_GREATER_EQUAL;
|
flipToken = T_GREATER_EQUAL;
|
||||||
break;
|
break;
|
||||||
@@ -262,7 +263,7 @@ private:
|
|||||||
return QApplication::translate("CppTools::QuickFix", "Rewrite Using %1").arg(replacement);
|
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;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -270,7 +271,8 @@ private:
|
|||||||
if (! replacement.isEmpty())
|
if (! replacement.isEmpty())
|
||||||
changes.replace(currentFile->range(binary->binary_op_token), replacement);
|
changes.replace(currentFile->range(binary->binary_op_token), replacement);
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -296,7 +298,7 @@ public:
|
|||||||
QList<QuickFixOperation::Ptr> result;
|
QList<QuickFixOperation::Ptr> result;
|
||||||
BinaryExpressionAST *expression = 0;
|
BinaryExpressionAST *expression = 0;
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
int index = path.size() - 1;
|
int index = path.size() - 1;
|
||||||
for (; index != -1; --index) {
|
for (; index != -1; --index) {
|
||||||
@@ -314,9 +316,9 @@ public:
|
|||||||
QSharedPointer<Operation> op(new Operation(interface));
|
QSharedPointer<Operation> op(new Operation(interface));
|
||||||
|
|
||||||
if (expression->match(op->pattern, &matcher) &&
|
if (expression->match(op->pattern, &matcher) &&
|
||||||
file.tokenAt(op->pattern->binary_op_token).is(T_AMPER_AMPER) &&
|
file->tokenAt(op->pattern->binary_op_token).is(T_AMPER_AMPER) &&
|
||||||
file.tokenAt(op->left->unary_op_token).is(T_EXCLAIM) &&
|
file->tokenAt(op->left->unary_op_token).is(T_EXCLAIM) &&
|
||||||
file.tokenAt(op->right->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->setDescription(QApplication::translate("CppTools::QuickFix", "Rewrite Condition Using ||"));
|
||||||
op->setPriority(index);
|
op->setPriority(index);
|
||||||
result.append(op);
|
result.append(op);
|
||||||
@@ -343,7 +345,7 @@ private:
|
|||||||
pattern = mk->BinaryExpression(left, right);
|
pattern = mk->BinaryExpression(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||"));
|
changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||"));
|
||||||
@@ -354,8 +356,9 @@ private:
|
|||||||
changes.insert(start, QLatin1String("!("));
|
changes.insert(start, QLatin1String("!("));
|
||||||
changes.insert(end, QLatin1String(")"));
|
changes.insert(end, QLatin1String(")"));
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(currentFile->range(pattern));
|
currentFile->appendIndentRange(currentFile->range(pattern));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -408,7 +411,7 @@ public:
|
|||||||
QList<CppQuickFixOperation::Ptr> result;
|
QList<CppQuickFixOperation::Ptr> result;
|
||||||
CoreDeclaratorAST *core_declarator = 0;
|
CoreDeclaratorAST *core_declarator = 0;
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
for (int index = path.size() - 1; index != -1; --index) {
|
for (int index = path.size() - 1; index != -1; --index) {
|
||||||
AST *node = path.at(index);
|
AST *node = path.at(index);
|
||||||
@@ -420,10 +423,10 @@ public:
|
|||||||
if (checkDeclaration(simpleDecl)) {
|
if (checkDeclaration(simpleDecl)) {
|
||||||
SimpleDeclarationAST *declaration = 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 startOfDeclSpecifier = file->startOf(declaration->decl_specifier_list->firstToken());
|
||||||
const int endOfDeclSpecifier = file.endOf(declaration->decl_specifier_list->lastToken() - 1);
|
const int endOfDeclSpecifier = file->endOf(declaration->decl_specifier_list->lastToken() - 1);
|
||||||
|
|
||||||
if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) {
|
if (cursorPosition >= startOfDeclSpecifier && cursorPosition <= endOfDeclSpecifier) {
|
||||||
// the AST node under cursor is a specifier.
|
// the AST node under cursor is a specifier.
|
||||||
@@ -455,7 +458,7 @@ private:
|
|||||||
"Split Declaration"));
|
"Split Declaration"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -481,8 +484,9 @@ private:
|
|||||||
prevDeclarator = declarator;
|
prevDeclarator = declarator;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(currentFile->range(declaration));
|
currentFile->appendIndentRange(currentFile->range(declaration));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -547,7 +551,7 @@ private:
|
|||||||
"Add Curly Braces"));
|
"Add Curly Braces"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -557,8 +561,9 @@ private:
|
|||||||
const int end = currentFile->endOf(_statement->lastToken() - 1);
|
const int end = currentFile->endOf(_statement->lastToken() - 1);
|
||||||
changes.insert(end, "\n}");
|
changes.insert(end, "\n}");
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(Utils::ChangeSet::Range(start, end));
|
currentFile->appendIndentRange(Utils::ChangeSet::Range(start, end));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -620,7 +625,7 @@ private:
|
|||||||
pattern = mk.IfStatement(condition);
|
pattern = mk.IfStatement(condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -630,8 +635,9 @@ private:
|
|||||||
changes.move(currentFile->range(condition), insertPos);
|
changes.move(currentFile->range(condition), insertPos);
|
||||||
changes.insert(insertPos, QLatin1String(";\n"));
|
changes.insert(insertPos, QLatin1String(";\n"));
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(currentFile->range(pattern));
|
currentFile->appendIndentRange(currentFile->range(pattern));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTMatcher matcher;
|
ASTMatcher matcher;
|
||||||
@@ -704,7 +710,7 @@ private:
|
|||||||
pattern = mk.WhileStatement(condition);
|
pattern = mk.WhileStatement(condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -717,8 +723,9 @@ private:
|
|||||||
changes.copy(currentFile->range(core), insertPos);
|
changes.copy(currentFile->range(core), insertPos);
|
||||||
changes.insert(insertPos, QLatin1String(";\n"));
|
changes.insert(insertPos, QLatin1String(";\n"));
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(currentFile->range(pattern));
|
currentFile->appendIndentRange(currentFile->range(pattern));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTMatcher matcher;
|
ASTMatcher matcher;
|
||||||
@@ -780,7 +787,7 @@ public:
|
|||||||
if (! condition)
|
if (! condition)
|
||||||
return noResult();
|
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
|
// only accept a chain of ||s or &&s - no mixing
|
||||||
if (! splitKind) {
|
if (! splitKind) {
|
||||||
@@ -815,7 +822,7 @@ private:
|
|||||||
"Split if Statement"));
|
"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);
|
const Token binaryToken = currentFile->tokenAt(condition->binary_op_token);
|
||||||
|
|
||||||
@@ -825,7 +832,7 @@ private:
|
|||||||
splitOrCondition(currentFile);
|
splitOrCondition(currentFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void splitAndCondition(CppRefactoringFile *currentFile)
|
void splitAndCondition(CppRefactoringFilePtr currentFile)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -838,11 +845,12 @@ private:
|
|||||||
changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
|
changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
|
||||||
changes.insert(currentFile->endOf(pattern), QLatin1String("\n}"));
|
changes.insert(currentFile->endOf(pattern), QLatin1String("\n}"));
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(currentFile->range(pattern));
|
currentFile->appendIndentRange(currentFile->range(pattern));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
void splitOrCondition(CppRefactoringFile *currentFile)
|
void splitOrCondition(CppRefactoringFilePtr currentFile)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -866,8 +874,9 @@ private:
|
|||||||
const int lExprEnd = currentFile->endOf(condition->left_expression);
|
const int lExprEnd = currentFile->endOf(condition->left_expression);
|
||||||
changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
|
changes.remove(lExprEnd, currentFile->startOf(condition->right_expression));
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(currentFile->range(pattern));
|
currentFile->appendIndentRange(currentFile->range(pattern));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -897,7 +906,7 @@ public:
|
|||||||
ExpressionAST *literal = 0;
|
ExpressionAST *literal = 0;
|
||||||
Type type = TypeNone;
|
Type type = TypeNone;
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return noResult(); // nothing to do
|
return noResult(); // nothing to do
|
||||||
@@ -906,7 +915,7 @@ public:
|
|||||||
|
|
||||||
if (! literal) {
|
if (! literal) {
|
||||||
literal = path.last()->asNumericLiteral();
|
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();
|
return noResult();
|
||||||
else
|
else
|
||||||
type = TypeChar;
|
type = TypeChar;
|
||||||
@@ -919,7 +928,7 @@ public:
|
|||||||
if (call->base_expression) {
|
if (call->base_expression) {
|
||||||
if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) {
|
if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) {
|
||||||
if (SimpleNameAST *functionName = idExpr->name->asSimpleName()) {
|
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"
|
if (id == "QT_TRANSLATE_NOOP" || id == "tr" || id == "trUtf8"
|
||||||
|| (type == TypeString && (id == "QLatin1String" || id == "QLatin1Literal"))
|
|| (type == TypeString && (id == "QLatin1String" || id == "QLatin1Literal"))
|
||||||
@@ -932,7 +941,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type == TypeString) {
|
if (type == TypeString) {
|
||||||
if (file.charAt(file.startOf(literal)) == QLatin1Char('@'))
|
if (file->charAt(file->startOf(literal)) == QLatin1Char('@'))
|
||||||
type = TypeObjCString;
|
type = TypeObjCString;
|
||||||
}
|
}
|
||||||
return singleResult(new Operation(interface,
|
return singleResult(new Operation(interface,
|
||||||
@@ -959,7 +968,7 @@ private:
|
|||||||
"Enclose in QLatin1String(...)"));
|
"Enclose in QLatin1String(...)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -974,7 +983,8 @@ private:
|
|||||||
|
|
||||||
changes.insert(currentFile->endOf(literal), ")");
|
changes.insert(currentFile->endOf(literal), ")");
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1019,7 +1029,7 @@ public:
|
|||||||
if (call->base_expression) {
|
if (call->base_expression) {
|
||||||
if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) {
|
if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) {
|
||||||
if (SimpleNameAST *functionName = idExpr->name->asSimpleName()) {
|
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"
|
if (id == "tr" || id == "trUtf8"
|
||||||
|| id == "translate"
|
|| id == "translate"
|
||||||
@@ -1083,7 +1093,7 @@ private:
|
|||||||
setDescription(QApplication::translate("CppTools::QuickFix", "Mark as Translatable"));
|
setDescription(QApplication::translate("CppTools::QuickFix", "Mark as Translatable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -1100,7 +1110,8 @@ private:
|
|||||||
changes.insert(startPos, replacement);
|
changes.insert(startPos, replacement);
|
||||||
changes.insert(currentFile->endOf(m_literal), QLatin1String(")"));
|
changes.insert(currentFile->endOf(m_literal), QLatin1String(")"));
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1125,7 +1136,7 @@ class CStringToNSString: public CppQuickFixFactory
|
|||||||
public:
|
public:
|
||||||
virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface)
|
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)
|
if (interface->editor()->mimeType() != CppTools::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)
|
||||||
return noResult();
|
return noResult();
|
||||||
@@ -1142,7 +1153,7 @@ public:
|
|||||||
if (! stringLiteral)
|
if (! stringLiteral)
|
||||||
return noResult();
|
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.
|
return noResult(); // it's already an objc string literal.
|
||||||
|
|
||||||
else if (path.size() > 1) {
|
else if (path.size() > 1) {
|
||||||
@@ -1150,7 +1161,7 @@ public:
|
|||||||
if (call->base_expression) {
|
if (call->base_expression) {
|
||||||
if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) {
|
if (IdExpressionAST *idExpr = call->base_expression->asIdExpression()) {
|
||||||
if (SimpleNameAST *functionName = idExpr->name->asSimpleName()) {
|
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")
|
if (id == "QLatin1String" || id == "QLatin1Literal")
|
||||||
qlatin1Call = call;
|
qlatin1Call = call;
|
||||||
@@ -1176,7 +1187,7 @@ private:
|
|||||||
"Convert to Objective-C String Literal"));
|
"Convert to Objective-C String Literal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
|
|
||||||
@@ -1187,7 +1198,8 @@ private:
|
|||||||
changes.insert(currentFile->startOf(stringLiteral), "@");
|
changes.insert(currentFile->startOf(stringLiteral), "@");
|
||||||
}
|
}
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1222,7 +1234,7 @@ public:
|
|||||||
QList<QuickFixOperation::Ptr> result;
|
QList<QuickFixOperation::Ptr> result;
|
||||||
|
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
return result; // nothing to do
|
return result; // nothing to do
|
||||||
@@ -1232,7 +1244,7 @@ public:
|
|||||||
if (! literal)
|
if (! literal)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
Token token = file.tokenAt(literal->asNumericLiteral()->literal_token);
|
Token token = file->tokenAt(literal->asNumericLiteral()->literal_token);
|
||||||
if (!token.is(T_NUMERIC_LITERAL))
|
if (!token.is(T_NUMERIC_LITERAL))
|
||||||
return result;
|
return result;
|
||||||
const NumericLiteral *numeric = token.number;
|
const NumericLiteral *numeric = token.number;
|
||||||
@@ -1254,7 +1266,7 @@ public:
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
const int priority = path.size() - 1; // very high priority
|
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();
|
const char * const str = numeric->chars();
|
||||||
|
|
||||||
if (!numeric->isHex()) {
|
if (!numeric->isHex()) {
|
||||||
@@ -1328,11 +1340,12 @@ private:
|
|||||||
, replacement(replacement)
|
, replacement(replacement)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile, const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
ChangeSet changes;
|
ChangeSet changes;
|
||||||
changes.replace(start, end, replacement);
|
changes.replace(start, end, replacement);
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -1407,7 +1420,8 @@ private:
|
|||||||
"#include Header File"));
|
"#include Header File"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(CppRefactoringFile *currentFile, CppRefactoringChanges *)
|
virtual void performChanges(const CppRefactoringFilePtr ¤tFile,
|
||||||
|
const CppRefactoringChanges &)
|
||||||
{
|
{
|
||||||
Q_ASSERT(fwdClass != 0);
|
Q_ASSERT(fwdClass != 0);
|
||||||
|
|
||||||
@@ -1464,7 +1478,8 @@ private:
|
|||||||
|
|
||||||
Utils::ChangeSet changes;
|
Utils::ChangeSet changes;
|
||||||
changes.insert(pos, QString("#include <%1>\n").arg(QFileInfo(best).fileName()));
|
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)
|
virtual QList<CppQuickFixOperation::Ptr> match(const QSharedPointer<const CppQuickFixAssistInterface> &interface)
|
||||||
{
|
{
|
||||||
const QList<AST *> &path = interface->path();
|
const QList<AST *> &path = interface->path();
|
||||||
const CppRefactoringFile &file = interface->currentFile();
|
CppRefactoringFilePtr file = interface->currentFile();
|
||||||
|
|
||||||
for (int index = path.size() - 1; index != -1; --index) {
|
for (int index = path.size() - 1; index != -1; --index) {
|
||||||
if (BinaryExpressionAST *binary = path.at(index)->asBinaryExpression()) {
|
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();
|
IdExpressionAST *idExpr = binary->left_expression->asIdExpression();
|
||||||
if (interface->isCursorOn(binary->left_expression) && idExpr && idExpr->name->asSimpleName() != 0) {
|
if (interface->isCursorOn(binary->left_expression) && idExpr && idExpr->name->asSimpleName() != 0) {
|
||||||
SimpleNameAST *nameAST = idExpr->name->asSimpleName();
|
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;
|
Declaration *decl = 0;
|
||||||
foreach (const LookupItem &r, results) {
|
foreach (const LookupItem &r, results) {
|
||||||
if (! r.declaration())
|
if (! r.declaration())
|
||||||
@@ -1531,7 +1546,8 @@ private:
|
|||||||
setDescription(QApplication::translate("CppTools::QuickFix", "Add Local Declaration"));
|
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 typeOfExpression;
|
||||||
typeOfExpression.init(assistInterface()->semanticInfo().doc,
|
typeOfExpression.init(assistInterface()->semanticInfo().doc,
|
||||||
@@ -1565,7 +1581,8 @@ private:
|
|||||||
|
|
||||||
Utils::ChangeSet changes;
|
Utils::ChangeSet changes;
|
||||||
changes.insert(currentFile->startOf(binaryAST), ty);
|
changes.insert(currentFile->startOf(binaryAST), ty);
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1626,7 +1643,8 @@ private:
|
|||||||
"Convert to Camel Case"));
|
"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) {
|
for (int i = 1; i < m_name.length(); ++i) {
|
||||||
QCharRef c = m_name[i];
|
QCharRef c = m_name[i];
|
||||||
|
@@ -49,64 +49,101 @@ using namespace CPlusPlus;
|
|||||||
using namespace CppTools;
|
using namespace CppTools;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
CppRefactoringChanges::CppRefactoringChanges(const Snapshot &snapshot)
|
class CppTools::CppRefactoringChangesData : public TextEditor::RefactoringChangesData
|
||||||
: m_snapshot(snapshot)
|
|
||||||
, m_modelManager(Internal::CppModelManager::instance())
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_modelManager);
|
public:
|
||||||
m_workingCopy = m_modelManager->workingCopy();
|
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)
|
||||||
|
: RefactoringChanges(new CppRefactoringChangesData(snapshot))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CppRefactoringChangesData *CppRefactoringChanges::data() const
|
||||||
|
{
|
||||||
|
return static_cast<CppRefactoringChangesData *>(m_data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
CppRefactoringFilePtr CppRefactoringChanges::file(TextEditor::BaseTextEditorWidget *editor, const Document::Ptr &document)
|
||||||
|
{
|
||||||
|
CppRefactoringFilePtr result(new CppRefactoringFile(editor));
|
||||||
|
result->setCppDocument(document);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
CppRefactoringFilePtr CppRefactoringChanges::file(const QString &fileName) const
|
||||||
|
{
|
||||||
|
CppRefactoringFilePtr result(new CppRefactoringFile(fileName, m_data));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Document::Ptr cppDocument = data()->m_snapshot.document(fileName);
|
||||||
|
if (cppDocument)
|
||||||
|
result->setCppDocument(cppDocument);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Snapshot &CppRefactoringChanges::snapshot() const
|
const Snapshot &CppRefactoringChanges::snapshot() const
|
||||||
{
|
{
|
||||||
return m_snapshot;
|
return data()->m_snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
CppRefactoringFile CppRefactoringChanges::file(const QString &fileName)
|
CppRefactoringFile::CppRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data)
|
||||||
|
: RefactoringFile(fileName, data)
|
||||||
{
|
{
|
||||||
return CppRefactoringFile(fileName, this);
|
const Snapshot &snapshot = this->data()->m_snapshot;
|
||||||
}
|
|
||||||
|
|
||||||
void CppRefactoringChanges::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);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CppRefactoringChanges::fileChanged(const QString &fileName)
|
|
||||||
{
|
|
||||||
m_modelManager->updateSourceFiles(QStringList(fileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CppRefactoringFile::CppRefactoringFile()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
CppRefactoringFile::CppRefactoringFile(const QString &fileName, CppRefactoringChanges *refactoringChanges)
|
|
||||||
: RefactoringFile(fileName, refactoringChanges)
|
|
||||||
{
|
|
||||||
const Snapshot &snapshot = refactoringChanges->snapshot();
|
|
||||||
m_cppDocument = snapshot.document(fileName);
|
m_cppDocument = snapshot.document(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +161,7 @@ Document::Ptr CppRefactoringFile::cppDocument() const
|
|||||||
!m_cppDocument->translationUnit()->ast()) {
|
!m_cppDocument->translationUnit()->ast()) {
|
||||||
const QString source = document()->toPlainText();
|
const QString source = document()->toPlainText();
|
||||||
const QString name = fileName();
|
const QString name = fileName();
|
||||||
const Snapshot &snapshot = refactoringChanges()->snapshot();
|
const Snapshot &snapshot = data()->m_snapshot;
|
||||||
|
|
||||||
const QByteArray contents = snapshot.preprocessedCode(source, name);
|
const QByteArray contents = snapshot.preprocessedCode(source, name);
|
||||||
m_cppDocument = snapshot.documentFromSource(contents, name);
|
m_cppDocument = snapshot.documentFromSource(contents, name);
|
||||||
@@ -233,7 +270,13 @@ const Token &CppRefactoringFile::tokenAt(unsigned index) const
|
|||||||
return cppDocument()->translationUnit()->tokenAt(index);
|
return cppDocument()->translationUnit()->tokenAt(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
CppRefactoringChanges *CppRefactoringFile::refactoringChanges() const
|
CppRefactoringChangesData *CppRefactoringFile::data() const
|
||||||
{
|
{
|
||||||
return static_cast<CppRefactoringChanges *>(m_refactoringChanges);
|
return static_cast<CppRefactoringChangesData *>(m_data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppRefactoringFile::fileChanged()
|
||||||
|
{
|
||||||
|
m_cppDocument.clear();
|
||||||
|
RefactoringFile::fileChanged();
|
||||||
}
|
}
|
||||||
|
@@ -45,14 +45,14 @@
|
|||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
class CppRefactoringChanges;
|
class CppRefactoringChanges;
|
||||||
|
class CppRefactoringFile;
|
||||||
|
class CppRefactoringChangesData;
|
||||||
|
typedef QSharedPointer<CppRefactoringFile> CppRefactoringFilePtr;
|
||||||
|
typedef QSharedPointer<const CppRefactoringFile> CppRefactoringFileConstPtr;
|
||||||
|
|
||||||
class CPPTOOLS_EXPORT CppRefactoringFile: public TextEditor::RefactoringFile
|
class CPPTOOLS_EXPORT CppRefactoringFile: public TextEditor::RefactoringFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CppRefactoringFile();
|
|
||||||
CppRefactoringFile(QTextDocument *document, const QString &fileName = QString());
|
|
||||||
CppRefactoringFile(TextEditor::BaseTextEditorWidget *editor);
|
|
||||||
|
|
||||||
CPlusPlus::Document::Ptr cppDocument() const;
|
CPlusPlus::Document::Ptr cppDocument() const;
|
||||||
void setCppDocument(CPlusPlus::Document::Ptr document);
|
void setCppDocument(CPlusPlus::Document::Ptr document);
|
||||||
|
|
||||||
@@ -78,10 +78,12 @@ public:
|
|||||||
QString textOf(const CPlusPlus::AST *ast) const;
|
QString textOf(const CPlusPlus::AST *ast) const;
|
||||||
|
|
||||||
protected:
|
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:
|
CppRefactoringChangesData *data() const;
|
||||||
CppRefactoringChanges *refactoringChanges() const;
|
virtual void fileChanged();
|
||||||
|
|
||||||
mutable CPlusPlus::Document::Ptr m_cppDocument;
|
mutable CPlusPlus::Document::Ptr m_cppDocument;
|
||||||
|
|
||||||
@@ -93,21 +95,16 @@ class CPPTOOLS_EXPORT CppRefactoringChanges: public TextEditor::RefactoringChang
|
|||||||
public:
|
public:
|
||||||
CppRefactoringChanges(const CPlusPlus::Snapshot &snapshot);
|
CppRefactoringChanges(const CPlusPlus::Snapshot &snapshot);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
const CPlusPlus::Snapshot &snapshot() const;
|
const CPlusPlus::Snapshot &snapshot() const;
|
||||||
CppRefactoringFile file(const QString &fileName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void indentSelection(const QTextCursor &selection,
|
CppRefactoringChangesData *data() const;
|
||||||
const QString &fileName,
|
|
||||||
const TextEditor::BaseTextEditorWidget *textEditor) const;
|
|
||||||
virtual void fileChanged(const QString &fileName);
|
|
||||||
|
|
||||||
private:
|
|
||||||
CPlusPlus::Document::Ptr m_thisDocument;
|
|
||||||
CPlusPlus::Snapshot m_snapshot;
|
|
||||||
CPlusPlus::LookupContext m_context;
|
|
||||||
CPlusPlus::CppModelManagerInterface *m_modelManager;
|
|
||||||
CPlusPlus::CppModelManagerInterface::WorkingCopy m_workingCopy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
@@ -287,7 +287,7 @@ InsertionLocation::InsertionLocation(const QString &fileName,
|
|||||||
, m_column(column)
|
, m_column(column)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
InsertionPointLocator::InsertionPointLocator(CppRefactoringChanges *refactoringChanges)
|
InsertionPointLocator::InsertionPointLocator(const CppRefactoringChanges &refactoringChanges)
|
||||||
: m_refactoringChanges(refactoringChanges)
|
: m_refactoringChanges(refactoringChanges)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -297,7 +297,7 @@ InsertionLocation InsertionPointLocator::methodDeclarationInClass(
|
|||||||
const Class *clazz,
|
const Class *clazz,
|
||||||
AccessSpec xsSpec) const
|
AccessSpec xsSpec) const
|
||||||
{
|
{
|
||||||
const Document::Ptr doc = m_refactoringChanges->file(fileName).cppDocument();
|
const Document::Ptr doc = m_refactoringChanges.file(fileName)->cppDocument();
|
||||||
if (doc) {
|
if (doc) {
|
||||||
FindInClass find(doc, clazz, xsSpec);
|
FindInClass find(doc, clazz, xsSpec);
|
||||||
return find();
|
return find();
|
||||||
@@ -434,11 +434,11 @@ QList<InsertionLocation> InsertionPointLocator::methodDefinition(
|
|||||||
target = candidate;
|
target = candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
Document::Ptr doc = m_refactoringChanges->file(target).cppDocument();
|
Document::Ptr doc = m_refactoringChanges.file(target)->cppDocument();
|
||||||
if (doc.isNull())
|
if (doc.isNull())
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
Snapshot simplified = m_refactoringChanges->snapshot().simplified(doc);
|
Snapshot simplified = m_refactoringChanges.snapshot().simplified(doc);
|
||||||
if (Symbol *s = simplified.findMatchingDefinition(declaration)) {
|
if (Symbol *s = simplified.findMatchingDefinition(declaration)) {
|
||||||
if (Function *f = s->asFunction()) {
|
if (Function *f = s->asFunction()) {
|
||||||
if (f->isConst() == declaration->type().isConst()
|
if (f->isConst() == declaration->type().isConst()
|
||||||
|
@@ -39,11 +39,10 @@
|
|||||||
#include <CPlusPlusForwardDeclarations.h>
|
#include <CPlusPlusForwardDeclarations.h>
|
||||||
|
|
||||||
#include <cplusplus/CppDocument.h>
|
#include <cplusplus/CppDocument.h>
|
||||||
|
#include <cpptools/cpprefactoringchanges.h>
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
|
|
||||||
class CppRefactoringChanges;
|
|
||||||
|
|
||||||
class CPPTOOLS_EXPORT InsertionLocation
|
class CPPTOOLS_EXPORT InsertionLocation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -100,7 +99,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InsertionPointLocator(CppRefactoringChanges *refactoringChanges);
|
InsertionPointLocator(const CppRefactoringChanges &refactoringChanges);
|
||||||
|
|
||||||
InsertionLocation methodDeclarationInClass(const QString &fileName,
|
InsertionLocation methodDeclarationInClass(const QString &fileName,
|
||||||
const CPlusPlus::Class *clazz,
|
const CPlusPlus::Class *clazz,
|
||||||
@@ -109,7 +108,7 @@ public:
|
|||||||
QList<InsertionLocation> methodDefinition(CPlusPlus::Declaration *declaration) const;
|
QList<InsertionLocation> methodDefinition(CPlusPlus::Declaration *declaration) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CppRefactoringChanges *m_refactoringChanges;
|
CppRefactoringChanges m_refactoringChanges;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
@@ -297,7 +297,7 @@ static void addDeclaration(const Snapshot &snapshot,
|
|||||||
declaration += QLatin1String(";\n");
|
declaration += QLatin1String(";\n");
|
||||||
|
|
||||||
CppTools::CppRefactoringChanges refactoring(snapshot);
|
CppTools::CppRefactoringChanges refactoring(snapshot);
|
||||||
CppTools::InsertionPointLocator find(&refactoring);
|
CppTools::InsertionPointLocator find(refactoring);
|
||||||
const CppTools::InsertionLocation loc = find.methodDeclarationInClass(
|
const CppTools::InsertionLocation loc = find.methodDeclarationInClass(
|
||||||
fileName, cl, CppTools::InsertionPointLocator::PrivateSlot);
|
fileName, cl, CppTools::InsertionPointLocator::PrivateSlot);
|
||||||
|
|
||||||
|
@@ -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 componentName = m_componentName;
|
||||||
QString path = QFileInfo(fileName()).path();
|
QString path = QFileInfo(fileName()).path();
|
||||||
@@ -142,7 +143,7 @@ public:
|
|||||||
+ QLatin1String("}\n");
|
+ QLatin1String("}\n");
|
||||||
|
|
||||||
// stop if we can't create the new file
|
// stop if we can't create the new file
|
||||||
if (!refactoring->createFile(newFileName, txt))
|
if (!refactoring.createFile(newFileName, txt))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString replacement = componentName + QLatin1String(" {\n");
|
QString replacement = componentName + QLatin1String(" {\n");
|
||||||
@@ -152,8 +153,9 @@ public:
|
|||||||
|
|
||||||
Utils::ChangeSet changes;
|
Utils::ChangeSet changes;
|
||||||
changes.replace(start, end, replacement);
|
changes.replace(start, end, replacement);
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(Range(start, end + 1));
|
currentFile->appendIndentRange(Range(start, end + 1));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,13 +165,13 @@ public:
|
|||||||
QList<QmlJSQuickFixOperation::Ptr> ComponentFromObjectDef::match(
|
QList<QmlJSQuickFixOperation::Ptr> ComponentFromObjectDef::match(
|
||||||
const QSharedPointer<const QmlJSQuickFixAssistInterface> &interface)
|
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);
|
QList<Node *> path = interface->semanticInfo().rangePath(pos);
|
||||||
for (int i = path.size() - 1; i >= 0; --i) {
|
for (int i = path.size() - 1; i >= 0; --i) {
|
||||||
Node *node = path.at(i);
|
Node *node = path.at(i);
|
||||||
if (UiObjectDefinition *objDef = cast<UiObjectDefinition *>(node)) {
|
if (UiObjectDefinition *objDef = cast<UiObjectDefinition *>(node)) {
|
||||||
if (!interface->currentFile().isCursorOn(objDef->qualifiedTypeNameId))
|
if (!interface->currentFile()->isCursorOn(objDef->qualifiedTypeNameId))
|
||||||
return noResult();
|
return noResult();
|
||||||
// check that the node is not the root node
|
// check that the node is not the root node
|
||||||
if (i > 0 && !cast<UiProgram*>(path.at(i - 1))) {
|
if (i > 0 && !cast<UiProgram*>(path.at(i - 1))) {
|
||||||
|
@@ -66,11 +66,10 @@ QmlJSQuickFixOperation::~QmlJSQuickFixOperation()
|
|||||||
void QmlJSQuickFixOperation::perform()
|
void QmlJSQuickFixOperation::perform()
|
||||||
{
|
{
|
||||||
QmlJSRefactoringChanges refactoring(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>(),
|
QmlJSRefactoringChanges refactoring(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>(),
|
||||||
//_state.snapshot());
|
|
||||||
m_interface->semanticInfo().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
|
const QmlJSQuickFixAssistInterface *QmlJSQuickFixOperation::assistInterface() const
|
||||||
|
@@ -79,8 +79,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
typedef Utils::ChangeSet::Range Range;
|
typedef Utils::ChangeSet::Range Range;
|
||||||
|
|
||||||
virtual void performChanges(QmlJSTools::QmlJSRefactoringFile *currentFile,
|
virtual void performChanges(QmlJSTools::QmlJSRefactoringFilePtr currentFile,
|
||||||
QmlJSTools::QmlJSRefactoringChanges *refactoring) = 0;
|
const QmlJSTools::QmlJSRefactoringChanges &refactoring) = 0;
|
||||||
|
|
||||||
const Internal::QmlJSQuickFixAssistInterface *assistInterface() const;
|
const Internal::QmlJSQuickFixAssistInterface *assistInterface() const;
|
||||||
|
|
||||||
|
@@ -51,6 +51,7 @@ QmlJSQuickFixAssistInterface::QmlJSQuickFixAssistInterface(QmlJSTextEditorWidget
|
|||||||
: DefaultAssistInterface(editor->document(), editor->position(), editor->file(), reason)
|
: DefaultAssistInterface(editor->document(), editor->position(), editor->file(), reason)
|
||||||
, m_editor(editor)
|
, m_editor(editor)
|
||||||
, m_semanticInfo(editor->semanticInfo())
|
, m_semanticInfo(editor->semanticInfo())
|
||||||
|
, m_currentFile(QmlJSRefactoringChanges::file(m_editor, m_semanticInfo.document))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
QmlJSQuickFixAssistInterface::~QmlJSQuickFixAssistInterface()
|
QmlJSQuickFixAssistInterface::~QmlJSQuickFixAssistInterface()
|
||||||
@@ -61,9 +62,9 @@ const SemanticInfo &QmlJSQuickFixAssistInterface::semanticInfo() const
|
|||||||
return m_semanticInfo;
|
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
|
QWidget *QmlJSQuickFixAssistInterface::widget() const
|
||||||
|
@@ -51,12 +51,13 @@ public:
|
|||||||
virtual ~QmlJSQuickFixAssistInterface();
|
virtual ~QmlJSQuickFixAssistInterface();
|
||||||
|
|
||||||
const SemanticInfo &semanticInfo() const;
|
const SemanticInfo &semanticInfo() const;
|
||||||
const QmlJSTools::QmlJSRefactoringFile currentFile() const;
|
QmlJSTools::QmlJSRefactoringFilePtr currentFile() const;
|
||||||
QWidget *widget() const;
|
QWidget *widget() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QmlJSTextEditorWidget *m_editor;
|
QmlJSTextEditorWidget *m_editor;
|
||||||
SemanticInfo m_semanticInfo;
|
SemanticInfo m_semanticInfo;
|
||||||
|
QmlJSTools::QmlJSRefactoringFilePtr m_currentFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -70,7 +70,7 @@ public:
|
|||||||
{
|
{
|
||||||
UiObjectInitializer *objectInitializer = 0;
|
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::Node *member = interface->semanticInfo().rangeAt(pos)) {
|
||||||
if (QmlJS::AST::UiObjectBinding *b = QmlJS::AST::cast<QmlJS::AST::UiObjectBinding *>(member)) {
|
if (QmlJS::AST::UiObjectBinding *b = QmlJS::AST::cast<QmlJS::AST::UiObjectBinding *>(member)) {
|
||||||
@@ -104,7 +104,8 @@ private:
|
|||||||
"Split initializer"));
|
"Split initializer"));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void performChanges(QmlJSRefactoringFile *currentFile, QmlJSRefactoringChanges *)
|
virtual void performChanges(QmlJSRefactoringFilePtr currentFile,
|
||||||
|
const QmlJSRefactoringChanges &)
|
||||||
{
|
{
|
||||||
Q_ASSERT(_objectInitializer != 0);
|
Q_ASSERT(_objectInitializer != 0);
|
||||||
|
|
||||||
@@ -123,9 +124,10 @@ private:
|
|||||||
changes.insert(currentFile->startOf(_objectInitializer->rbraceToken),
|
changes.insert(currentFile->startOf(_objectInitializer->rbraceToken),
|
||||||
QLatin1String("\n"));
|
QLatin1String("\n"));
|
||||||
|
|
||||||
currentFile->change(changes);
|
currentFile->setChangeSet(changes);
|
||||||
currentFile->indent(Range(currentFile->startOf(_objectInitializer->lbraceToken),
|
currentFile->appendIndentRange(Range(currentFile->startOf(_objectInitializer->lbraceToken),
|
||||||
currentFile->startOf(_objectInitializer->rbraceToken)));
|
currentFile->startOf(_objectInitializer->rbraceToken)));
|
||||||
|
currentFile->apply();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -775,11 +775,12 @@ void QmlOutlineModel::reparentNodes(QmlOutlineItem *targetItem, int row, QList<Q
|
|||||||
}
|
}
|
||||||
|
|
||||||
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), m_semanticInfo.snapshot);
|
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), m_semanticInfo.snapshot);
|
||||||
TextEditor::RefactoringFile file = refactoring.file(m_semanticInfo.document->fileName());
|
TextEditor::RefactoringFilePtr file = refactoring.file(m_semanticInfo.document->fileName());
|
||||||
file.change(changeSet);
|
file->setChangeSet(changeSet);
|
||||||
foreach (const Utils::ChangeSet::Range &range, changedRanges) {
|
foreach (const Utils::ChangeSet::Range &range, changedRanges) {
|
||||||
file.indent(range);
|
file->appendIndentRange(range);
|
||||||
}
|
}
|
||||||
|
file->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlOutlineModel::moveObjectMember(AST::UiObjectMember *toMove,
|
void QmlOutlineModel::moveObjectMember(AST::UiObjectMember *toMove,
|
||||||
|
@@ -43,65 +43,82 @@
|
|||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
using namespace QmlJSTools;
|
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,
|
QmlJSRefactoringChanges::QmlJSRefactoringChanges(ModelManagerInterface *modelManager,
|
||||||
const Snapshot &snapshot)
|
const Snapshot &snapshot)
|
||||||
: m_modelManager(modelManager)
|
: RefactoringChanges(new QmlJSRefactoringChangesData(modelManager, snapshot))
|
||||||
, m_snapshot(snapshot)
|
|
||||||
{
|
{
|
||||||
Q_ASSERT(modelManager);
|
}
|
||||||
|
|
||||||
|
QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file(const QString &fileName) const
|
||||||
|
{
|
||||||
|
return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(fileName, m_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file(
|
||||||
|
TextEditor::BaseTextEditorWidget *editor, const Document::Ptr &document)
|
||||||
|
{
|
||||||
|
return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(editor, document));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Snapshot &QmlJSRefactoringChanges::snapshot() const
|
const Snapshot &QmlJSRefactoringChanges::snapshot() const
|
||||||
{
|
{
|
||||||
return m_snapshot;
|
return data()->m_snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlJSRefactoringFile QmlJSRefactoringChanges::file(const QString &fileName)
|
QmlJSRefactoringChangesData *QmlJSRefactoringChanges::data() const
|
||||||
{
|
{
|
||||||
return QmlJSRefactoringFile(fileName, this);
|
return static_cast<QmlJSRefactoringChangesData *>(m_data.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlJSRefactoringChanges::indentSelection(const QTextCursor &selection,
|
QmlJSRefactoringFile::QmlJSRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data)
|
||||||
const QString &fileName,
|
: RefactoringFile(fileName, data)
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document)
|
QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document)
|
||||||
: RefactoringFile()
|
: RefactoringFile(editor)
|
||||||
, m_qmljsDocument(document)
|
, m_qmljsDocument(document)
|
||||||
{
|
{
|
||||||
m_fileName = document->fileName();
|
m_fileName = document->fileName();
|
||||||
m_editor = editor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Document::Ptr QmlJSRefactoringFile::qmljsDocument() const
|
Document::Ptr QmlJSRefactoringFile::qmljsDocument() const
|
||||||
@@ -109,7 +126,7 @@ Document::Ptr QmlJSRefactoringFile::qmljsDocument() const
|
|||||||
if (!m_qmljsDocument) {
|
if (!m_qmljsDocument) {
|
||||||
const QString source = document()->toPlainText();
|
const QString source = document()->toPlainText();
|
||||||
const QString name = fileName();
|
const QString name = fileName();
|
||||||
const Snapshot &snapshot = refactoringChanges()->snapshot();
|
const Snapshot &snapshot = data()->m_snapshot;
|
||||||
|
|
||||||
m_qmljsDocument = snapshot.documentFromSource(source, name);
|
m_qmljsDocument = snapshot.documentFromSource(source, name);
|
||||||
m_qmljsDocument->parse();
|
m_qmljsDocument->parse();
|
||||||
@@ -145,7 +162,13 @@ bool QmlJSRefactoringFile::isCursorOn(AST::UiQualifiedId *ast) const
|
|||||||
return pos <= ast->identifierToken.end();
|
return pos <= ast->identifierToken.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlJSRefactoringChanges *QmlJSRefactoringFile::refactoringChanges() const
|
QmlJSRefactoringChangesData *QmlJSRefactoringFile::data() const
|
||||||
{
|
{
|
||||||
return static_cast<QmlJSRefactoringChanges *>(m_refactoringChanges);
|
return static_cast<QmlJSRefactoringChangesData *>(m_data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlJSRefactoringFile::fileChanged()
|
||||||
|
{
|
||||||
|
m_qmljsDocument.clear();
|
||||||
|
RefactoringFile::fileChanged();
|
||||||
}
|
}
|
||||||
|
@@ -46,14 +46,13 @@ class ModelManagerInterface;
|
|||||||
namespace QmlJSTools {
|
namespace QmlJSTools {
|
||||||
|
|
||||||
class QmlJSRefactoringChanges;
|
class QmlJSRefactoringChanges;
|
||||||
|
class QmlJSRefactoringFile;
|
||||||
|
class QmlJSRefactoringChangesData;
|
||||||
|
typedef QSharedPointer<QmlJSRefactoringFile> QmlJSRefactoringFilePtr;
|
||||||
|
|
||||||
class QMLJSTOOLS_EXPORT QmlJSRefactoringFile: public TextEditor::RefactoringFile
|
class QMLJSTOOLS_EXPORT QmlJSRefactoringFile: public TextEditor::RefactoringFile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QmlJSRefactoringFile();
|
|
||||||
QmlJSRefactoringFile(const QString &fileName, QmlJSRefactoringChanges *refactoringChanges);
|
|
||||||
QmlJSRefactoringFile(TextEditor::BaseTextEditorWidget *editor, QmlJS::Document::Ptr document);
|
|
||||||
|
|
||||||
QmlJS::Document::Ptr qmljsDocument() const;
|
QmlJS::Document::Ptr qmljsDocument() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -65,10 +64,16 @@ public:
|
|||||||
bool isCursorOn(QmlJS::AST::UiObjectMember *ast) const;
|
bool isCursorOn(QmlJS::AST::UiObjectMember *ast) const;
|
||||||
bool isCursorOn(QmlJS::AST::UiQualifiedId *ast) const;
|
bool isCursorOn(QmlJS::AST::UiQualifiedId *ast) const;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
QmlJSRefactoringChanges *refactoringChanges() const;
|
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;
|
mutable QmlJS::Document::Ptr m_qmljsDocument;
|
||||||
|
|
||||||
|
friend class QmlJSRefactoringChanges;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -78,19 +83,14 @@ public:
|
|||||||
QmlJSRefactoringChanges(QmlJS::ModelManagerInterface *modelManager,
|
QmlJSRefactoringChanges(QmlJS::ModelManagerInterface *modelManager,
|
||||||
const QmlJS::Snapshot &snapshot);
|
const QmlJS::Snapshot &snapshot);
|
||||||
|
|
||||||
|
static QmlJSRefactoringFilePtr file(TextEditor::BaseTextEditorWidget *editor,
|
||||||
|
const QmlJS::Document::Ptr &document);
|
||||||
|
QmlJSRefactoringFilePtr file(const QString &fileName) const;
|
||||||
|
|
||||||
const QmlJS::Snapshot &snapshot() const;
|
const QmlJS::Snapshot &snapshot() const;
|
||||||
|
|
||||||
QmlJSRefactoringFile file(const QString &fileName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void indentSelection(const QTextCursor &selection,
|
QmlJSRefactoringChangesData *data() const;
|
||||||
const QString &fileName,
|
|
||||||
const TextEditor::BaseTextEditorWidget *textEditor) const;
|
|
||||||
virtual void fileChanged(const QString &fileName);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QmlJS::ModelManagerInterface *m_modelManager;
|
|
||||||
QmlJS::Snapshot m_snapshot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlJSTools
|
} // namespace QmlJSTools
|
||||||
|
@@ -169,7 +169,7 @@ Core::IEditor *BaseTextEditorWidget::openEditorAt(const QString &fileName, int l
|
|||||||
Core::IEditor *editor = editorManager->openEditor(fileName, editorKind,
|
Core::IEditor *editor = editorManager->openEditor(fileName, editorKind,
|
||||||
flags, newEditor);
|
flags, newEditor);
|
||||||
TextEditor::ITextEditor *texteditor = qobject_cast<TextEditor::ITextEditor *>(editor);
|
TextEditor::ITextEditor *texteditor = qobject_cast<TextEditor::ITextEditor *>(editor);
|
||||||
if (texteditor) {
|
if (texteditor && line != -1) {
|
||||||
texteditor->gotoLine(line, column);
|
texteditor->gotoLine(line, column);
|
||||||
return texteditor;
|
return texteditor;
|
||||||
}
|
}
|
||||||
|
@@ -50,17 +50,17 @@
|
|||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
|
|
||||||
RefactoringChanges::RefactoringChanges()
|
RefactoringChanges::RefactoringChanges()
|
||||||
|
: m_data(new RefactoringChangesData)
|
||||||
|
{}
|
||||||
|
|
||||||
|
RefactoringChanges::RefactoringChanges(RefactoringChangesData *data)
|
||||||
|
: m_data(data)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RefactoringChanges::~RefactoringChanges()
|
RefactoringChanges::~RefactoringChanges()
|
||||||
{
|
{}
|
||||||
if (!m_fileToOpen.isEmpty()) {
|
|
||||||
BaseTextEditorWidget::openEditorAt(m_fileToOpen, m_lineToOpen, m_columnToOpen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseTextEditorWidget *RefactoringChanges::editorForFile(const QString &fileName,
|
BaseTextEditorWidget *RefactoringChanges::editorForFile(const QString &fileName)
|
||||||
bool openIfClosed)
|
|
||||||
{
|
{
|
||||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
|
|
||||||
@@ -70,20 +70,7 @@ BaseTextEditorWidget *RefactoringChanges::editorForFile(const QString &fileName,
|
|||||||
if (textEditor != 0)
|
if (textEditor != 0)
|
||||||
return textEditor;
|
return textEditor;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QTextCursor> RefactoringChanges::rangesToSelections(QTextDocument *document, const QList<Range> &ranges)
|
QList<QTextCursor> RefactoringChanges::rangesToSelections(QTextDocument *document, const QList<Range> &ranges)
|
||||||
@@ -102,12 +89,15 @@ QList<QTextCursor> RefactoringChanges::rangesToSelections(QTextDocument *documen
|
|||||||
return selections;
|
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))
|
if (QFile::exists(fileName))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BaseTextEditorWidget *editor = editorForFile(fileName, openEditor);
|
BaseTextEditorWidget *editor = editorForFile(fileName);
|
||||||
|
if (!editor && openEditor) {
|
||||||
|
editor = this->openEditor(fileName, false, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
QTextDocument *document;
|
QTextDocument *document;
|
||||||
if (editor)
|
if (editor)
|
||||||
@@ -123,7 +113,7 @@ bool RefactoringChanges::createFile(const QString &fileName, const QString &cont
|
|||||||
|
|
||||||
if (reindent) {
|
if (reindent) {
|
||||||
cursor.select(QTextCursor::Document);
|
cursor.select(QTextCursor::Document);
|
||||||
indentSelection(cursor, fileName, editor);
|
m_data->indentSelection(cursor, fileName, editor);
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.endEditBlock();
|
cursor.endEditBlock();
|
||||||
@@ -137,12 +127,12 @@ bool RefactoringChanges::createFile(const QString &fileName, const QString &cont
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fileChanged(fileName);
|
m_data->fileChanged(fileName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RefactoringChanges::removeFile(const QString &fileName)
|
bool RefactoringChanges::removeFile(const QString &fileName) const
|
||||||
{
|
{
|
||||||
if (!QFile::exists(fileName))
|
if (!QFile::exists(fileName))
|
||||||
return false;
|
return false;
|
||||||
@@ -152,119 +142,70 @@ bool RefactoringChanges::removeFile(const QString &fileName)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefactoringFile RefactoringChanges::file(const QString &fileName)
|
BaseTextEditorWidget *RefactoringChanges::openEditor(const QString &fileName, bool activate, int line, int column)
|
||||||
{
|
{
|
||||||
if (QFile::exists(fileName))
|
Core::EditorManager::OpenEditorFlags flags = Core::EditorManager::IgnoreNavigationHistory;
|
||||||
return RefactoringFile(fileName, this);
|
if (!activate)
|
||||||
else
|
flags |= Core::EditorManager::NoActivate;
|
||||||
return RefactoringFile();
|
if (line != -1) {
|
||||||
}
|
// openEditorAt uses a 1-based line and a 0-based column!
|
||||||
|
column -= 1;
|
||||||
BaseTextEditorWidget *RefactoringChanges::openEditor(const QString &fileName, int pos)
|
|
||||||
{
|
|
||||||
BaseTextEditorWidget *editor = editorForFile(fileName, true);
|
|
||||||
if (pos != -1) {
|
|
||||||
QTextCursor cursor = editor->textCursor();
|
|
||||||
cursor.setPosition(pos);
|
|
||||||
editor->setTextCursor(cursor);
|
|
||||||
}
|
}
|
||||||
return editor;
|
Core::IEditor *editor = BaseTextEditorWidget::openEditorAt(
|
||||||
|
fileName, line, column, QString(), flags);
|
||||||
|
return qobject_cast<BaseTextEditorWidget *>(editor->widget());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RefactoringChanges::activateEditor(const QString &fileName, int line, int column)
|
RefactoringFilePtr RefactoringChanges::file(BaseTextEditorWidget *editor)
|
||||||
{
|
{
|
||||||
m_fileToOpen = fileName;
|
return RefactoringFilePtr(new RefactoringFile(editor));
|
||||||
m_lineToOpen = line;
|
|
||||||
m_columnToOpen = column;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RefactoringFilePtr RefactoringChanges::file(const QString &fileName) const
|
||||||
RefactoringFile::RefactoringFile()
|
{
|
||||||
: m_refactoringChanges(0)
|
return RefactoringFilePtr(new RefactoringFile(fileName, m_data));
|
||||||
, m_document(0)
|
}
|
||||||
, m_editor(0)
|
|
||||||
, m_openEditor(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
RefactoringFile::RefactoringFile(QTextDocument *document, const QString &fileName)
|
RefactoringFile::RefactoringFile(QTextDocument *document, const QString &fileName)
|
||||||
: m_fileName(fileName)
|
: m_fileName(fileName)
|
||||||
, m_refactoringChanges(0)
|
|
||||||
, m_document(document)
|
, m_document(document)
|
||||||
, m_editor(0)
|
, m_editor(0)
|
||||||
, m_openEditor(false)
|
, m_openEditor(false)
|
||||||
|
, m_activateEditor(false)
|
||||||
|
, m_editorCursorPosition(-1)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
RefactoringFile::RefactoringFile(BaseTextEditorWidget *editor)
|
RefactoringFile::RefactoringFile(BaseTextEditorWidget *editor)
|
||||||
: m_fileName(editor->file()->fileName())
|
: m_fileName(editor->file()->fileName())
|
||||||
, m_refactoringChanges(0)
|
|
||||||
, m_document(0)
|
, m_document(0)
|
||||||
, m_editor(editor)
|
, m_editor(editor)
|
||||||
, m_openEditor(false)
|
, 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_fileName(fileName)
|
||||||
, m_refactoringChanges(refactoringChanges)
|
, m_data(data)
|
||||||
, m_document(0)
|
, m_document(0)
|
||||||
, m_editor(0)
|
, m_editor(0)
|
||||||
, m_openEditor(false)
|
, m_openEditor(false)
|
||||||
|
, m_activateEditor(false)
|
||||||
|
, m_editorCursorPosition(-1)
|
||||||
{
|
{
|
||||||
m_editor = RefactoringChanges::editorForFile(fileName, false);
|
m_editor = RefactoringChanges::editorForFile(fileName);
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RefactoringFile::~RefactoringFile()
|
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;
|
delete m_document;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RefactoringFile::isValid() const
|
bool RefactoringFile::isValid() const
|
||||||
{
|
{
|
||||||
return !m_fileName.isEmpty();
|
if (m_fileName.isEmpty())
|
||||||
|
return false;
|
||||||
|
return document();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QTextDocument *RefactoringFile::document() const
|
const QTextDocument *RefactoringFile::document() const
|
||||||
@@ -278,7 +219,7 @@ QTextDocument *RefactoringFile::mutableDocument() const
|
|||||||
return m_editor->document();
|
return m_editor->document();
|
||||||
else if (!m_document) {
|
else if (!m_document) {
|
||||||
QString fileContents;
|
QString fileContents;
|
||||||
if (!m_fileName.isEmpty()) {
|
if (!m_fileName.isEmpty() && QFile::exists(m_fileName)) {
|
||||||
Utils::FileReader reader;
|
Utils::FileReader reader;
|
||||||
if (reader.fetch(m_fileName, Core::ICore::instance()->mainWindow()))
|
if (reader.fetch(m_fileName, Core::ICore::instance()->mainWindow()))
|
||||||
fileContents = QString::fromUtf8(reader.data());
|
fileContents = QString::fromUtf8(reader.data());
|
||||||
@@ -292,8 +233,10 @@ const QTextCursor RefactoringFile::cursor() const
|
|||||||
{
|
{
|
||||||
if (m_editor)
|
if (m_editor)
|
||||||
return m_editor->textCursor();
|
return m_editor->textCursor();
|
||||||
else if (!m_fileName.isEmpty())
|
else if (!m_fileName.isEmpty()) {
|
||||||
return QTextCursor(mutableDocument());
|
if (QTextDocument *doc = mutableDocument())
|
||||||
|
return QTextCursor(doc);
|
||||||
|
}
|
||||||
|
|
||||||
return QTextCursor();
|
return QTextCursor();
|
||||||
}
|
}
|
||||||
@@ -312,6 +255,17 @@ int RefactoringFile::position(unsigned line, unsigned column) const
|
|||||||
return -1;
|
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
|
QChar RefactoringFile::charAt(int pos) const
|
||||||
{
|
{
|
||||||
if (const QTextDocument *doc = document())
|
if (const QTextDocument *doc = document())
|
||||||
@@ -332,28 +286,87 @@ QString RefactoringFile::textOf(const Range &range) const
|
|||||||
return textOf(range.start, range.end);
|
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())
|
if (m_fileName.isEmpty())
|
||||||
return false;
|
return;
|
||||||
if (!m_changes.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_changes = changeSet;
|
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())
|
if (m_fileName.isEmpty())
|
||||||
return false;
|
return;
|
||||||
|
|
||||||
m_indentRanges.append(range);
|
m_indentRanges.append(range);
|
||||||
|
}
|
||||||
if (openEditor)
|
|
||||||
m_openEditor = true;
|
void RefactoringFile::setOpenEditor(bool activate, int pos)
|
||||||
|
{
|
||||||
return true;
|
m_openEditor = true;
|
||||||
|
m_activateEditor = activate;
|
||||||
|
m_editorCursorPosition = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 &)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
@@ -38,57 +38,69 @@
|
|||||||
|
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QTextDocument)
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QTextDocument;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
class BaseTextEditorWidget;
|
class BaseTextEditorWidget;
|
||||||
class RefactoringChanges;
|
class RefactoringChanges;
|
||||||
|
class RefactoringFile;
|
||||||
|
class RefactoringChangesData;
|
||||||
|
typedef QSharedPointer<RefactoringFile> RefactoringFilePtr;
|
||||||
|
|
||||||
|
// ### listen to the m_editor::destroyed signal?
|
||||||
class TEXTEDITOR_EXPORT RefactoringFile
|
class TEXTEDITOR_EXPORT RefactoringFile
|
||||||
{
|
{
|
||||||
|
Q_DISABLE_COPY(RefactoringFile)
|
||||||
public:
|
public:
|
||||||
typedef Utils::ChangeSet::Range Range;
|
typedef Utils::ChangeSet::Range Range;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RefactoringFile();
|
|
||||||
// takes ownership of document
|
|
||||||
RefactoringFile(QTextDocument *document, const QString &fileName = QString());
|
|
||||||
RefactoringFile(BaseTextEditorWidget *editor);
|
|
||||||
RefactoringFile(const RefactoringFile &other);
|
|
||||||
virtual ~RefactoringFile();
|
virtual ~RefactoringFile();
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
|
|
||||||
const QTextDocument *document() const;
|
const QTextDocument *document() const;
|
||||||
|
// mustn't use the cursor to change the document
|
||||||
const QTextCursor cursor() const;
|
const QTextCursor cursor() const;
|
||||||
QString fileName() 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;
|
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;
|
QChar charAt(int pos) const;
|
||||||
QString textOf(int start, int end) const;
|
QString textOf(int start, int end) const;
|
||||||
QString textOf(const Range &range) const;
|
QString textOf(const Range &range) const;
|
||||||
|
|
||||||
bool change(const Utils::ChangeSet &changeSet, bool openEditor = true);
|
void setChangeSet(const Utils::ChangeSet &changeSet);
|
||||||
bool indent(const Range &range, bool openEditor = true);
|
void appendIndentRange(const Range &range);
|
||||||
|
void setOpenEditor(bool activate = false, int pos = -1);
|
||||||
|
void apply();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// not assignable
|
RefactoringFile(QTextDocument *document, const QString &fileName);
|
||||||
//const RefactoringFile &operator=(const RefactoringFile &other);
|
RefactoringFile(BaseTextEditorWidget *editor);
|
||||||
|
RefactoringFile(const QString &fileName, const QSharedPointer<RefactoringChangesData> &data);
|
||||||
|
|
||||||
RefactoringFile(const QString &fileName, RefactoringChanges *refactoringChanges);
|
|
||||||
QTextDocument *mutableDocument() const;
|
QTextDocument *mutableDocument() const;
|
||||||
|
// derived classes may want to clear language specific extra data
|
||||||
|
virtual void fileChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString m_fileName;
|
QString m_fileName;
|
||||||
RefactoringChanges *m_refactoringChanges;
|
QSharedPointer<RefactoringChangesData> m_data;
|
||||||
mutable QTextDocument *m_document;
|
mutable QTextDocument *m_document;
|
||||||
BaseTextEditorWidget *m_editor;
|
BaseTextEditorWidget *m_editor;
|
||||||
Utils::ChangeSet m_changes;
|
Utils::ChangeSet m_changes;
|
||||||
QList<Range> m_indentRanges;
|
QList<Range> m_indentRanges;
|
||||||
bool m_openEditor;
|
bool m_openEditor;
|
||||||
|
bool m_activateEditor;
|
||||||
|
int m_editorCursorPosition;
|
||||||
|
|
||||||
friend class RefactoringChanges; // access to constructor
|
friend class RefactoringChanges; // access to constructor
|
||||||
};
|
};
|
||||||
@@ -106,36 +118,37 @@ public:
|
|||||||
RefactoringChanges();
|
RefactoringChanges();
|
||||||
virtual ~RefactoringChanges();
|
virtual ~RefactoringChanges();
|
||||||
|
|
||||||
bool createFile(const QString &fileName, const QString &contents, bool reindent = true, bool openEditor = true);
|
static RefactoringFilePtr file(BaseTextEditorWidget *editor);
|
||||||
bool removeFile(const QString &fileName);
|
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);
|
protected:
|
||||||
|
explicit RefactoringChanges(RefactoringChangesData *data);
|
||||||
|
|
||||||
/*!
|
static BaseTextEditorWidget *openEditor(const QString &fileName, bool activate, int line, int column);
|
||||||
\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);
|
|
||||||
|
|
||||||
static BaseTextEditorWidget *editorForFile(const QString &fileName,
|
|
||||||
bool openIfClosed = false);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static QList<QTextCursor> rangesToSelections(QTextDocument *document, const QList<Range> &ranges);
|
static QList<QTextCursor> rangesToSelections(QTextDocument *document, const QList<Range> &ranges);
|
||||||
virtual void indentSelection(const QTextCursor &selection,
|
|
||||||
const QString &fileName,
|
protected:
|
||||||
const BaseTextEditorWidget *textEditor) const = 0;
|
QSharedPointer<RefactoringChangesData> m_data;
|
||||||
virtual void fileChanged(const QString &fileName) = 0;
|
|
||||||
|
|
||||||
friend class RefactoringFile;
|
friend class RefactoringFile;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
class TEXTEDITOR_EXPORT RefactoringChangesData
|
||||||
QString m_fileToOpen;
|
{
|
||||||
int m_lineToOpen;
|
Q_DISABLE_COPY(RefactoringChangesData)
|
||||||
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
|
} // namespace TextEditor
|
||||||
|
Reference in New Issue
Block a user