forked from qt-creator/qt-creator
CppEditor: Fix InsertDefFromDecl::match
Now InsertDefFromDecl finds the right implementation file and the speed of match() is improved. Task-number: QTCREATORBUG-9627 Change-Id: Ibff824f52124e8cc10ccb6a97c133e11565473db Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
89225167fb
commit
b7ba23f92d
@@ -162,6 +162,7 @@ private slots:
|
||||
void test_quickfix_InsertDefFromDecl_insideClass();
|
||||
void test_quickfix_InsertDefFromDecl_notTriggeringWhenDefinitionExists();
|
||||
void test_quickfix_InsertDefFromDecl_notTriggeringStatement();
|
||||
void test_quickfix_InsertDefFromDecl_findRightImplementationFile();
|
||||
|
||||
void test_quickfix_InsertDeclFromDef();
|
||||
|
||||
|
@@ -1126,6 +1126,58 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_notTriggeringStatement()
|
||||
data.run(&factory);
|
||||
}
|
||||
|
||||
/// Find right implementation file.
|
||||
void CppEditorPlugin::test_quickfix_InsertDefFromDecl_findRightImplementationFile()
|
||||
{
|
||||
QList<TestDocumentPtr> testFiles;
|
||||
|
||||
QByteArray original;
|
||||
QByteArray expected;
|
||||
|
||||
// Header File
|
||||
original =
|
||||
"struct Foo\n"
|
||||
"{\n"
|
||||
" Foo();\n"
|
||||
" void a();\n"
|
||||
" void b@();\n"
|
||||
"};\n"
|
||||
"}\n";
|
||||
expected = original + "\n";
|
||||
testFiles << TestDocument::create(original, expected, QLatin1String("file.h"));
|
||||
|
||||
// Source File #1
|
||||
original =
|
||||
"#include \"file.h\"\n"
|
||||
"\n"
|
||||
"Foo::Foo()\n"
|
||||
"{\n\n"
|
||||
"}\n"
|
||||
"\n";
|
||||
expected = original + "\n";
|
||||
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
|
||||
|
||||
|
||||
// Source File #2
|
||||
original =
|
||||
"#include \"file.h\"\n"
|
||||
"\n"
|
||||
"void Foo::a()\n"
|
||||
"{\n\n"
|
||||
"}\n";
|
||||
expected = original +
|
||||
"\n"
|
||||
"void Foo::b()\n"
|
||||
"{\n\n"
|
||||
"}\n"
|
||||
"\n";
|
||||
testFiles << TestDocument::create(original, expected, QLatin1String("file2.cpp"));
|
||||
|
||||
InsertDefFromDecl factory;
|
||||
TestCase data(testFiles);
|
||||
data.run(&factory);
|
||||
}
|
||||
|
||||
// Function for one of InsertDeclDef section cases
|
||||
void insertToSectionDeclFromDef(const QByteArray §ion, int sectionIndex)
|
||||
{
|
||||
|
@@ -2480,20 +2480,23 @@ namespace {
|
||||
class InsertDefOperation: public CppQuickFixOperation
|
||||
{
|
||||
public:
|
||||
// Make sure that either loc is valid or targetFileName is not empty.
|
||||
InsertDefOperation(const QSharedPointer<const CppQuickFixAssistInterface> &interface,
|
||||
Declaration *decl, const InsertionLocation &loc, const DefPos defpos,
|
||||
bool freeFunction = false)
|
||||
const QString &targetFileName = QString(), bool freeFunction = false)
|
||||
: CppQuickFixOperation(interface, 0)
|
||||
, m_decl(decl)
|
||||
, m_loc(loc)
|
||||
, m_defpos(defpos)
|
||||
, m_targetFileName(targetFileName)
|
||||
{
|
||||
if (m_defpos == DefPosImplementationFile) {
|
||||
const QString declFile = QString::fromUtf8(decl->fileName(), decl->fileNameLength());
|
||||
const QDir dir = QFileInfo(declFile).dir();
|
||||
setDescription(QCoreApplication::translate("CppEditor::InsertDefOperation",
|
||||
"Add Definition in %1")
|
||||
.arg(dir.relativeFilePath(m_loc.fileName())));
|
||||
.arg(dir.relativeFilePath(m_loc.isValid() ? m_loc.fileName()
|
||||
: m_targetFileName)));
|
||||
} else if (freeFunction) {
|
||||
setDescription(QCoreApplication::translate("CppEditor::InsertDefOperation",
|
||||
"Add Definition Here"));
|
||||
@@ -2508,10 +2511,12 @@ public:
|
||||
|
||||
void perform()
|
||||
{
|
||||
QTC_ASSERT(m_loc.isValid(), return);
|
||||
CppRefactoringChanges refactoring(snapshot());
|
||||
CppRefactoringFilePtr targetFile = refactoring.file(m_loc.fileName());
|
||||
if (!m_loc.isValid())
|
||||
m_loc = insertLocationForMethodDefinition(m_decl, true, refactoring, m_targetFileName);
|
||||
QTC_ASSERT(m_loc.isValid(), return);
|
||||
|
||||
CppRefactoringFilePtr targetFile = refactoring.file(m_loc.fileName());
|
||||
Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview();
|
||||
oo.showFunctionSignatures = true;
|
||||
oo.showReturnTypes = true;
|
||||
@@ -2585,8 +2590,9 @@ public:
|
||||
|
||||
private:
|
||||
Declaration *m_decl;
|
||||
const InsertionLocation m_loc;
|
||||
InsertionLocation m_loc;
|
||||
const DefPos m_defpos;
|
||||
const QString m_targetFileName;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
@@ -2615,53 +2621,52 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe
|
||||
return;
|
||||
}
|
||||
|
||||
InsertDefOperation *op = 0;
|
||||
bool isHeaderFile = false;
|
||||
const QString cppFileName = correspondingHeaderOrSource(
|
||||
interface->fileName(), &isHeaderFile);
|
||||
InsertionLocation loc;
|
||||
|
||||
// Insert Position: Implementation File
|
||||
if (isHeaderFile && !cppFileName.isEmpty()) {
|
||||
InsertDefOperation *op = 0;
|
||||
ProjectFile::Kind kind = ProjectFile::classify(interface->fileName());
|
||||
const bool isHeaderFile = ProjectFile::isHeader(kind);
|
||||
if (isHeaderFile) {
|
||||
CppRefactoringChanges refactoring(interface->snapshot());
|
||||
loc = insertLocationForMethodDefinition(decl, true, refactoring,
|
||||
cppFileName);
|
||||
if (loc.isValid()) {
|
||||
op = new InsertDefOperation(interface, decl, loc,
|
||||
DefPosImplementationFile);
|
||||
result.append(CppQuickFixOperation::Ptr(op));
|
||||
InsertionPointLocator locator(refactoring);
|
||||
// find appropriate implementation file, but do not use this
|
||||
// location, because insertLocationForMethodDefinition() should
|
||||
// be used in perform() to get consistent insert positions.
|
||||
foreach (const InsertionLocation &location,
|
||||
locator.methodDefinition(decl, false, QString())) {
|
||||
if (location.isValid()) {
|
||||
op = new InsertDefOperation(interface, decl,
|
||||
InsertionLocation(),
|
||||
DefPosImplementationFile,
|
||||
location.fileName());
|
||||
result.append(CppQuickFixOperation::Ptr(op));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dealing with a free function
|
||||
const CppRefactoringFilePtr file = interface->currentFile();
|
||||
unsigned line, column;
|
||||
if (func->enclosingClass() == 0) {
|
||||
file->lineAndColumn(file->endOf(simpleDecl), &line, &column);
|
||||
loc = InsertionLocation(interface->fileName(), QLatin1String(""),
|
||||
QLatin1String(""), line, column);
|
||||
op = new InsertDefOperation(interface, decl, loc,
|
||||
DefPosInsideClass, true);
|
||||
result.append(CppQuickFixOperation::Ptr(op));
|
||||
return;
|
||||
}
|
||||
// Determine if we are dealing with a free function
|
||||
const bool isFreeFunction = func->enclosingClass() == 0;
|
||||
|
||||
// Insert Position: Outside Class
|
||||
CppRefactoringChanges refactoring(interface->snapshot());
|
||||
loc = insertLocationForMethodDefinition(decl, true, refactoring,
|
||||
interface->fileName());
|
||||
if (loc.isValid()) {
|
||||
op = new InsertDefOperation(interface, decl, loc,
|
||||
DefPosOutsideClass);
|
||||
if (!isFreeFunction) {
|
||||
op = new InsertDefOperation(interface, decl, InsertionLocation(),
|
||||
DefPosOutsideClass,
|
||||
interface->fileName());
|
||||
result.append(CppQuickFixOperation::Ptr(op));
|
||||
}
|
||||
|
||||
// Insert Position: Inside Class
|
||||
// Determine insert location direct after the declaration.
|
||||
unsigned line, column;
|
||||
const CppRefactoringFilePtr file = interface->currentFile();
|
||||
file->lineAndColumn(file->endOf(simpleDecl), &line, &column);
|
||||
loc = InsertionLocation(interface->fileName(), QLatin1String(""),
|
||||
QLatin1String(""), line, column);
|
||||
op = new InsertDefOperation(interface, decl, loc, DefPosInsideClass);
|
||||
const InsertionLocation loc
|
||||
= InsertionLocation(interface->fileName(), QString(), QString(),
|
||||
line, column);
|
||||
op = new InsertDefOperation(interface, decl, loc, DefPosInsideClass,
|
||||
QString() , isFreeFunction);
|
||||
result.append(CppQuickFixOperation::Ptr(op));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user