Index: lib/Format/FormatTokenLexer.cpp =================================================================== --- lib/Format/FormatTokenLexer.cpp +++ lib/Format/FormatTokenLexer.cpp @@ -82,6 +82,19 @@ if (tryMergeTokens(JSRightArrow, TT_JsFatArrow)) return; } + + if (Style.Language == FormatStyle::LK_Java) { + static const tok::TokenKind JavaRightLogicalShift[] = {tok::greater, + tok::greater, + tok::greater}; + static const tok::TokenKind JavaRightLogicalShiftAssign[] = {tok::greater, + tok::greater, + tok::greaterequal}; + if (tryMergeTokens(JavaRightLogicalShift, TT_BinaryOperator)) + return; + if (tryMergeTokens(JavaRightLogicalShiftAssign, TT_BinaryOperator)) + return; + } } bool FormatTokenLexer::tryMergeLessLess() { Index: unittests/Format/FormatTestJava.cpp =================================================================== --- unittests/Format/FormatTestJava.cpp +++ unittests/Format/FormatTestJava.cpp @@ -522,5 +522,17 @@ " void f() {}")); } +TEST_F(FormatTestJava, RetainsLogicalShifts) { + verifyFormat("void f() {\n" + " int a = 1;\n" + " a >>>= 1;\n" + "}"); + verifyFormat("void f() {\n" + " int a = 1;\n" + " a = a >>> 1;\n" + "}"); +} + + } // end namespace tooling } // end namespace clang