Index: clang/lib/Format/WhitespaceManager.h =================================================================== --- clang/lib/Format/WhitespaceManager.h +++ clang/lib/Format/WhitespaceManager.h @@ -174,6 +174,9 @@ /// \brief Align consecutive C/C++ preprocessor macros over all \c Changes. void alignConsecutiveMacros(); + /// TODO(jbcoe) + void alignChainedCSharpMethodInvocations(); + /// Align consecutive assignments over all \c Changes. void alignConsecutiveAssignments(); Index: clang/lib/Format/WhitespaceManager.cpp =================================================================== --- clang/lib/Format/WhitespaceManager.cpp +++ clang/lib/Format/WhitespaceManager.cpp @@ -92,6 +92,7 @@ llvm::sort(Changes, Change::IsBeforeInFile(SourceMgr)); calculateLineBreakInformation(); alignConsecutiveMacros(); + alignChainedCSharpMethodInvocations(); alignConsecutiveDeclarations(); alignConsecutiveAssignments(); alignTrailingComments(); @@ -553,6 +554,15 @@ FoundMatchOnLine, AlignMacrosMatches, Changes); } +void WhitespaceManager::alignChainedCSharpMethodInvocations() { + if (!Style.isCSharp()) + return; + + AlignTokens( + Style, [&](const Change &C) { return C.Tok->is(tok::period); }, Changes, + /*StartAt=*/0); +} + void WhitespaceManager::alignConsecutiveAssignments() { if (!Style.AlignConsecutiveAssignments) return; Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -554,5 +554,21 @@ Style); } +TEST_F(FormatTestCSharp, CSharpChainedMethodInvocations) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); + + verifyFormat(R"(// +var processed = someNumbers.Select(number => number * 2) + .Where(number => number != 6) + .OrderBy(number => number);)", + Style); + + // See if additional .'s cause issues. + verifyFormat(R"(// +var processed = someValues.someNumbers.Select(number => number.value * 2) + .Where(number => number.value != 6) + .OrderBy(number => number.value);)", + Style); +} } // namespace format } // end namespace clang