Author: djasper Date: Mon Nov 23 02:36:35 2015 New Revision: 253860 URL: http://llvm.org/viewvc/llvm-project?rev=253860&view=rev Log: clang-format: Make moving of the Cursor work properly when sorting #includes.
Modified: cfe/trunk/include/clang/Format/Format.h cfe/trunk/lib/Format/Format.cpp cfe/trunk/tools/clang-format/ClangFormat.cpp cfe/trunk/unittests/Format/SortIncludesTest.cpp Modified: cfe/trunk/include/clang/Format/Format.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=253860&r1=253859&r2=253860&view=diff ============================================================================== --- cfe/trunk/include/clang/Format/Format.h (original) +++ cfe/trunk/include/clang/Format/Format.h Mon Nov 23 02:36:35 2015 @@ -688,7 +688,8 @@ std::string configurationAsText(const Fo /// are affected by 'Ranges'. tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, - StringRef FileName); + StringRef FileName, + unsigned *Cursor = nullptr); /// \brief Reformats the given \p Ranges in the file \p ID. /// Modified: cfe/trunk/lib/Format/Format.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=253860&r1=253859&r2=253860&view=diff ============================================================================== --- cfe/trunk/lib/Format/Format.cpp (original) +++ cfe/trunk/lib/Format/Format.cpp Mon Nov 23 02:36:35 2015 @@ -1706,7 +1706,7 @@ static bool affectsRange(ArrayRef<toolin static void sortIncludes(const FormatStyle &Style, const SmallVectorImpl<IncludeDirective> &Includes, ArrayRef<tooling::Range> Ranges, StringRef FileName, - tooling::Replacements &Replaces) { + tooling::Replacements &Replaces, unsigned *Cursor) { if (!affectsRange(Ranges, Includes.front().Offset, Includes.back().Offset + Includes.back().Text.size())) return; @@ -1730,10 +1730,21 @@ static void sortIncludes(const FormatSty if (!OutOfOrder) return; - std::string result = Includes[Indices[0]].Text; - for (unsigned i = 1, e = Indices.size(); i != e; ++i) { - result += "\n"; - result += Includes[Indices[i]].Text; + std::string result; + bool CursorMoved = false; + for (unsigned Index : Indices) { + if (!result.empty()) + result += "\n"; + result += Includes[Index].Text; + + if (Cursor && !CursorMoved) { + unsigned Start = Includes[Index].Offset; + unsigned End = Start + Includes[Index].Text.size(); + if (*Cursor >= Start && *Cursor < End) { + *Cursor = Includes.front().Offset + result.size() + *Cursor - End; + CursorMoved = true; + } + } } // Sorting #includes shouldn't change their total number of characters. @@ -1748,7 +1759,7 @@ static void sortIncludes(const FormatSty tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, - StringRef FileName) { + StringRef FileName, unsigned *Cursor) { tooling::Replacements Replaces; if (!Style.SortIncludes) return Replaces; @@ -1811,7 +1822,8 @@ tooling::Replacements sortIncludes(const LookForMainHeader = false; IncludesInBlock.push_back({IncludeName, Line, Prev, Category}); } else if (!IncludesInBlock.empty()) { - sortIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces); + sortIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, + Cursor); IncludesInBlock.clear(); } Prev = Pos + 1; @@ -1821,7 +1833,7 @@ tooling::Replacements sortIncludes(const SearchFrom = Pos + 1; } if (!IncludesInBlock.empty()) - sortIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces); + sortIncludes(Style, IncludesInBlock, Ranges, FileName, Replaces, Cursor); return Replaces; } Modified: cfe/trunk/tools/clang-format/ClangFormat.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-format/ClangFormat.cpp?rev=253860&r1=253859&r2=253860&view=diff ============================================================================== --- cfe/trunk/tools/clang-format/ClangFormat.cpp (original) +++ cfe/trunk/tools/clang-format/ClangFormat.cpp Mon Nov 23 02:36:35 2015 @@ -140,18 +140,18 @@ static bool fillRanges(MemoryBuffer *Cod InMemoryFileSystem.get()); if (!LineRanges.empty()) { if (!Offsets.empty() || !Lengths.empty()) { - llvm::errs() << "error: cannot use -lines with -offset/-length\n"; + errs() << "error: cannot use -lines with -offset/-length\n"; return true; } for (unsigned i = 0, e = LineRanges.size(); i < e; ++i) { unsigned FromLine, ToLine; if (parseLineRange(LineRanges[i], FromLine, ToLine)) { - llvm::errs() << "error: invalid <start line>:<end line> pair\n"; + errs() << "error: invalid <start line>:<end line> pair\n"; return true; } if (FromLine > ToLine) { - llvm::errs() << "error: start line should be less than end line\n"; + errs() << "error: start line should be less than end line\n"; return true; } SourceLocation Start = Sources.translateLineCol(ID, FromLine, 1); @@ -169,14 +169,12 @@ static bool fillRanges(MemoryBuffer *Cod Offsets.push_back(0); if (Offsets.size() != Lengths.size() && !(Offsets.size() == 1 && Lengths.empty())) { - llvm::errs() - << "error: number of -offset and -length arguments must match.\n"; + errs() << "error: number of -offset and -length arguments must match.\n"; return true; } for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { if (Offsets[i] >= Code->getBufferSize()) { - llvm::errs() << "error: offset " << Offsets[i] - << " is outside the file\n"; + errs() << "error: offset " << Offsets[i] << " is outside the file\n"; return true; } SourceLocation Start = @@ -184,9 +182,9 @@ static bool fillRanges(MemoryBuffer *Cod SourceLocation End; if (i < Lengths.size()) { if (Offsets[i] + Lengths[i] > Code->getBufferSize()) { - llvm::errs() << "error: invalid length " << Lengths[i] - << ", offset + length (" << Offsets[i] + Lengths[i] - << ") is outside the file.\n"; + errs() << "error: invalid length " << Lengths[i] + << ", offset + length (" << Offsets[i] + Lengths[i] + << ") is outside the file.\n"; return true; } End = Start.getLocWithOffset(Lengths[i]); @@ -206,26 +204,26 @@ static void outputReplacementXML(StringR size_t From = 0; size_t Index; while ((Index = Text.find_first_of("\n\r<&", From)) != StringRef::npos) { - llvm::outs() << Text.substr(From, Index - From); + outs() << Text.substr(From, Index - From); switch (Text[Index]) { case '\n': - llvm::outs() << " "; + outs() << " "; break; case '\r': - llvm::outs() << " "; + outs() << " "; break; case '<': - llvm::outs() << "<"; + outs() << "<"; break; case '&': - llvm::outs() << "&"; + outs() << "&"; break; default: llvm_unreachable("Unexpected character encountered!"); } From = Index + 1; } - llvm::outs() << Text.substr(From); + outs() << Text.substr(From); } static void outputReplacementsXML(const Replacements &Replaces) { @@ -243,7 +241,7 @@ static bool format(StringRef FileName) { ErrorOr<std::unique_ptr<MemoryBuffer>> CodeOrErr = MemoryBuffer::getFileOrSTDIN(FileName); if (std::error_code EC = CodeOrErr.getError()) { - llvm::errs() << EC.message() << "\n"; + errs() << EC.message() << "\n"; return true; } std::unique_ptr<llvm::MemoryBuffer> Code = std::move(CodeOrErr.get()); @@ -256,28 +254,29 @@ static bool format(StringRef FileName) { FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle); if (SortIncludes.getNumOccurrences() != 0) FormatStyle.SortIncludes = SortIncludes; - Replacements Replaces = - sortIncludes(FormatStyle, Code->getBuffer(), Ranges, AssumedFileName); + unsigned CursorPosition = Cursor; + Replacements Replaces = sortIncludes(FormatStyle, Code->getBuffer(), Ranges, + AssumedFileName, &CursorPosition); std::string ChangedCode = tooling::applyAllReplacements(Code->getBuffer(), Replaces); for (const auto &R : Replaces) Ranges.push_back({R.getOffset(), R.getLength()}); bool IncompleteFormat = false; - Replaces = tooling::mergeReplacements( - Replaces, reformat(FormatStyle, ChangedCode, Ranges, AssumedFileName, - &IncompleteFormat)); + Replacements FormatChanges = reformat(FormatStyle, ChangedCode, Ranges, + AssumedFileName, &IncompleteFormat); + Replaces = tooling::mergeReplacements(Replaces, FormatChanges); if (OutputXML) { - llvm::outs() << "<?xml version='1.0'?>\n<replacements " - "xml:space='preserve' incomplete_format='" - << (IncompleteFormat ? "true" : "false") << "'>\n"; + outs() << "<?xml version='1.0'?>\n<replacements " + "xml:space='preserve' incomplete_format='" + << (IncompleteFormat ? "true" : "false") << "'>\n"; if (Cursor.getNumOccurrences() != 0) - llvm::outs() << "<cursor>" - << tooling::shiftedCodePosition(Replaces, Cursor) - << "</cursor>\n"; + outs() << "<cursor>" + << tooling::shiftedCodePosition(FormatChanges, CursorPosition) + << "</cursor>\n"; outputReplacementsXML(Replaces); - llvm::outs() << "</replacements>\n"; + outs() << "</replacements>\n"; } else { IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem( new vfs::InMemoryFileSystem); @@ -292,13 +291,13 @@ static bool format(StringRef FileName) { tooling::applyAllReplacements(Replaces, Rewrite); if (Inplace) { if (FileName == "-") - llvm::errs() << "error: cannot use -i when reading from stdin.\n"; + errs() << "error: cannot use -i when reading from stdin.\n"; else if (Rewrite.overwriteChangedFiles()) return true; } else { if (Cursor.getNumOccurrences() != 0) outs() << "{ \"Cursor\": " - << tooling::shiftedCodePosition(Replaces, Cursor) + << tooling::shiftedCodePosition(FormatChanges, CursorPosition) << ", \"IncompleteFormat\": " << (IncompleteFormat ? "true" : "false") << " }\n"; Rewrite.getEditBuffer(ID).write(outs()); @@ -338,7 +337,7 @@ int main(int argc, const char **argv) { clang::format::configurationAsText(clang::format::getStyle( Style, FileNames.empty() ? AssumeFileName : FileNames[0], FallbackStyle)); - llvm::outs() << Config << "\n"; + outs() << Config << "\n"; return 0; } @@ -352,8 +351,8 @@ int main(int argc, const char **argv) { break; default: if (!Offsets.empty() || !Lengths.empty() || !LineRanges.empty()) { - llvm::errs() << "error: -offset, -length and -lines can only be used for " - "single file.\n"; + errs() << "error: -offset, -length and -lines can only be used for " + "single file.\n"; return 1; } for (unsigned i = 0; i < FileNames.size(); ++i) Modified: cfe/trunk/unittests/Format/SortIncludesTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/SortIncludesTest.cpp?rev=253860&r1=253859&r2=253860&view=diff ============================================================================== --- cfe/trunk/unittests/Format/SortIncludesTest.cpp (original) +++ cfe/trunk/unittests/Format/SortIncludesTest.cpp Mon Nov 23 02:36:35 2015 @@ -28,7 +28,14 @@ protected: reformat(Style, Sorted, Ranges, FileName)); } + unsigned newCursor(llvm::StringRef Code, unsigned Cursor) { + std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); + sortIncludes(Style, Code, Ranges, "input.cpp", &Cursor); + return Cursor; + } + FormatStyle Style = getLLVMStyle(); + }; TEST_F(SortIncludesTest, BasicSorting) { @@ -178,6 +185,19 @@ TEST_F(SortIncludesTest, LeavesMainHeade "some_header.h")); } +TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { + std::string Code = "#include <ccc>\n" // Start of line: 0 + "#include <bbbbbb>\n" // Start of line: 15 + "#include <a>\n"; // Start of line: 33 + EXPECT_EQ(31u, newCursor(Code, 0)); + EXPECT_EQ(13u, newCursor(Code, 15)); + EXPECT_EQ(0u, newCursor(Code, 33)); + + EXPECT_EQ(41u, newCursor(Code, 10)); + EXPECT_EQ(23u, newCursor(Code, 25)); + EXPECT_EQ(10u, newCursor(Code, 43)); +} + } // end namespace } // end namespace format } // end namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits