forked from qt-creator/qt-creator
C++: do not strip trailing newlines in the preprocessor output.
Doing so resulted in an incorrect position for the EOF token when the preprocessed output would be parsed. That in turn leads to incorrect insertion positions for refactoring actions. This is especially true when a file contains only preprocessor directives: the EOF token would point to line 1 column 1, which is usually not the place where code should be inserted. Change-Id: I7d359aa7a6c04bc52c8b873fd49ad6afc3a77319 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
committed by
Erik Verbruggen
parent
271a96b19a
commit
f2631ad031
@@ -1332,19 +1332,6 @@ void Preprocessor::synchronizeOutputLines(const PPToken &tk, bool forceLine)
|
||||
adjustForCommentOrStringNewlines(&m_env->currentLine, tk);
|
||||
}
|
||||
|
||||
void Preprocessor::removeTrailingOutputLines()
|
||||
{
|
||||
QByteArray &buffer = currentOutputBuffer();
|
||||
int i = buffer.size() - 1;
|
||||
while (i >= 0 && buffer.at(i) == '\n')
|
||||
--i;
|
||||
const int mightChop = buffer.size() - i - 1;
|
||||
if (mightChop > 1) {
|
||||
// Keep one new line at end.
|
||||
buffer.chop(mightChop - 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t Preprocessor::computeDistance(const Preprocessor::PPToken &tk, bool forceTillLine)
|
||||
{
|
||||
// Find previous non-space character or line begin.
|
||||
@@ -1450,8 +1437,6 @@ void Preprocessor::preprocess(const QString &fileName, const QByteArray &source,
|
||||
|
||||
} while (tk.isNot(T_EOF_SYMBOL));
|
||||
|
||||
removeTrailingOutputLines();
|
||||
|
||||
if (includeGuardMacroName) {
|
||||
if (m_state.m_includeGuardState == State::IncludeGuardState_AfterDefine
|
||||
|| m_state.m_includeGuardState == State::IncludeGuardState_AfterEndif)
|
||||
|
@@ -237,7 +237,6 @@ private:
|
||||
void maybeStartOutputLine();
|
||||
void generateOutputLineMarker(unsigned lineno);
|
||||
void synchronizeOutputLines(const PPToken &tk, bool forceLine = false);
|
||||
void removeTrailingOutputLines();
|
||||
|
||||
void enforceSpacing(const PPToken &tk, bool forceSpacing = false);
|
||||
static std::size_t computeDistance(const PPToken &tk, bool forceTillLine = false);
|
||||
|
@@ -842,17 +842,17 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_headerSource_namespace2()
|
||||
|
||||
// Source File
|
||||
original =
|
||||
"#include \"file.h\"\n"
|
||||
"using namespace N;\n"
|
||||
"\n"
|
||||
;
|
||||
"#include \"file.h\"\n"
|
||||
"using namespace N;\n"
|
||||
;
|
||||
expected = original +
|
||||
"\n"
|
||||
"Foo::Foo()\n"
|
||||
"{\n\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
;
|
||||
"\n"
|
||||
"\n"
|
||||
"Foo::Foo()\n"
|
||||
"{\n\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
;
|
||||
testFiles << TestDocument::create(original, expected, QLatin1String("file.cpp"));
|
||||
|
||||
InsertDefFromDecl factory;
|
||||
|
@@ -10,4 +10,3 @@ private:
|
||||
public:
|
||||
Test();
|
||||
};
|
||||
|
||||
|
@@ -1 +1,9 @@
|
||||
# 1 "data/identifier-expansion.5.cpp"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -10,3 +10,8 @@ void thisFunctionIsEnabled();
|
||||
void thisFunctionIsEnabled2();
|
||||
# 31 "data/macro-test.cpp"
|
||||
void thisFunctionIsEnabled3();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -353,6 +353,8 @@ private slots:
|
||||
void skip_unknown_directives_data();
|
||||
void include_guard();
|
||||
void include_guard_data();
|
||||
void empty_trailing_lines();
|
||||
void empty_trailing_lines_data();
|
||||
};
|
||||
|
||||
// Remove all #... lines, and 'simplify' string, to allow easily comparing the result
|
||||
@@ -1507,7 +1509,13 @@ void tst_Preprocessor::skip_unknown_directives_data()
|
||||
"# 10 \"file.cpp\"\n"
|
||||
"# ()\n"
|
||||
"#\n";
|
||||
expected = "# 1 \"<stdin>\"\n";
|
||||
expected =
|
||||
"# 1 \"<stdin>\"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
;
|
||||
QTest::newRow("case 1") << original << expected;
|
||||
}
|
||||
|
||||
@@ -1593,6 +1601,74 @@ void tst_Preprocessor::include_guard_data()
|
||||
;
|
||||
}
|
||||
|
||||
void tst_Preprocessor::empty_trailing_lines()
|
||||
{
|
||||
compare_input_output();
|
||||
}
|
||||
|
||||
void tst_Preprocessor::empty_trailing_lines_data()
|
||||
{
|
||||
// Test if the number of lines at the end of a file is correct. This is important to make the
|
||||
// EOF token for the end up at the correct line.
|
||||
|
||||
QTest::addColumn<QByteArray>("input");
|
||||
QTest::addColumn<QByteArray>("output");
|
||||
|
||||
QByteArray original;
|
||||
QByteArray expected;
|
||||
|
||||
original =
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
;
|
||||
expected = "# 1 \"<stdin>\"\n" + original;
|
||||
QTest::newRow("9 empty lines") << original << expected;
|
||||
|
||||
original =
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
;
|
||||
expected =
|
||||
"# 1 \"<stdin>\"\n"
|
||||
"# 11 \"<stdin>\"\n"
|
||||
;
|
||||
QTest::newRow("11 empty lines") << original << expected;
|
||||
|
||||
original =
|
||||
"#include <something>\n"
|
||||
;
|
||||
expected =
|
||||
"# 1 \"<stdin>\"\n"
|
||||
"\n"
|
||||
;
|
||||
QTest::newRow("1 include") << original << expected;
|
||||
|
||||
original =
|
||||
"#include <something>\n"
|
||||
"\n"
|
||||
;
|
||||
expected =
|
||||
"# 1 \"<stdin>\"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
;
|
||||
QTest::newRow("1 empty line with 1 include") << original << expected;
|
||||
}
|
||||
|
||||
void tst_Preprocessor::compare_input_output(bool keepComments)
|
||||
{
|
||||
QFETCH(QByteArray, input);
|
||||
@@ -1602,7 +1678,7 @@ void tst_Preprocessor::compare_input_output(bool keepComments)
|
||||
Preprocessor preprocess(0, &env);
|
||||
preprocess.setKeepComments(keepComments);
|
||||
QByteArray prep = preprocess.run(QLatin1String("<stdin>"), input);
|
||||
QCOMPARE(output, prep);
|
||||
QCOMPARE(prep.constData(), output.constData());
|
||||
}
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_Preprocessor)
|
||||
|
Reference in New Issue
Block a user