From 09db0594445a414fe41ef989534be9f7a333b050 Mon Sep 17 00:00:00 2001 From: Nico Weber <nicolasweber@gmx.de> Date: Tue, 11 Apr 2017 15:50:04 +0000 Subject: [PATCH] [clang-format] Recognize Java logical shift assignment operator At present, clang-format mangles Java containing logical right shift operators ('>>>=' or '>>>'), splitting them in two, resulting in invalid code: public class Minimal { public void func(String args) { int i = 42; - i >>>= 1; + i >> >= 1; return i; } } This adds both forms of logical right shift to the FormatTokenLexer, so clang-format won't attempt to split them and insert bogus whitespace. https://reviews.llvm.org/D31652 Patch from Richard Bradfield <bradfier@fstab.me>! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@299952 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Format/FormatTokenLexer.cpp | 13 +++++++++++++ unittests/Format/FormatTestJava.cpp | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp index 9415dbe9ab3..4ee43d6937e 100644 --- a/lib/Format/FormatTokenLexer.cpp +++ b/lib/Format/FormatTokenLexer.cpp @@ -84,6 +84,19 @@ void FormatTokenLexer::tryMergePreviousTokens() { 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::tryMergeNSStringLiteral() { diff --git a/unittests/Format/FormatTestJava.cpp b/unittests/Format/FormatTestJava.cpp index ee09ca940f1..6e685f6703e 100644 --- a/unittests/Format/FormatTestJava.cpp +++ b/unittests/Format/FormatTestJava.cpp @@ -522,5 +522,17 @@ TEST_F(FormatTestJava, AlignsBlockComments) { " 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 -- GitLab