[clang-tools-extra] [llvm] [clangd] Add CodeAction to swap operands to binary operators (PR #78999)

2024-02-11 Thread Tor Shepherd via cfe-commits

https://github.com/torshepherd updated 
https://github.com/llvm/llvm-project/pull/78999

>From 6abe2b5af090329bfca42d144597fbd5ca41d511 Mon Sep 17 00:00:00 2001
From: Tor Shepherd 
Date: Sun, 21 Jan 2024 17:53:31 -0500
Subject: [PATCH] [clangd] Swap binary operands

---
 .../clangd/refactor/tweaks/CMakeLists.txt |   1 +
 .../refactor/tweaks/SwapBinaryOperands.cpp| 210 ++
 .../clangd/unittests/CMakeLists.txt   |   1 +
 .../tweaks/SwapBinaryOperandsTests.cpp|  38 
 .../clangd/refactor/tweaks/BUILD.gn   |   1 +
 .../clangd/unittests/BUILD.gn |   1 +
 6 files changed, 252 insertions(+)
 create mode 100644 
clang-tools-extra/clangd/refactor/tweaks/SwapBinaryOperands.cpp
 create mode 100644 
clang-tools-extra/clangd/unittests/tweaks/SwapBinaryOperandsTests.cpp

diff --git a/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt 
b/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
index 2e948c23569f68..59475b0dfd3d22 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
+++ b/clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
@@ -29,6 +29,7 @@ add_clang_library(clangDaemonTweaks OBJECT
   RemoveUsingNamespace.cpp
   ScopifyEnum.cpp
   SpecialMembers.cpp
+  SwapBinaryOperands.cpp
   SwapIfBranches.cpp
 
   LINK_LIBS
diff --git a/clang-tools-extra/clangd/refactor/tweaks/SwapBinaryOperands.cpp 
b/clang-tools-extra/clangd/refactor/tweaks/SwapBinaryOperands.cpp
new file mode 100644
index 00..2241b0ac37b52a
--- /dev/null
+++ b/clang-tools-extra/clangd/refactor/tweaks/SwapBinaryOperands.cpp
@@ -0,0 +1,210 @@
+//===--- SwapBinaryOperands.cpp --*- 
C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+#include "ParsedAST.h"
+#include "SourceCode.h"
+#include "refactor/Tweak.h"
+#include "support/Logger.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Tooling/Core/Replacement.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Error.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+/// Check whether it makes logical sense to swap operands to an operator.
+/// Assignment or member access operators are rarely swappable
+/// while keeping the meaning intact, whereas comparison operators, 
mathematical
+/// operators, etc. are often desired to be swappable for readability, avoiding
+/// bugs by assigning to nullptr when comparison was desired, etc.
+auto isOpSwappable(const BinaryOperatorKind Opcode) -> bool {
+  switch (Opcode) {
+  case BinaryOperatorKind::BO_Mul:
+  case BinaryOperatorKind::BO_Add:
+  case BinaryOperatorKind::BO_Cmp:
+  case BinaryOperatorKind::BO_LT:
+  case BinaryOperatorKind::BO_GT:
+  case BinaryOperatorKind::BO_LE:
+  case BinaryOperatorKind::BO_GE:
+  case BinaryOperatorKind::BO_EQ:
+  case BinaryOperatorKind::BO_NE:
+  case BinaryOperatorKind::BO_And:
+  case BinaryOperatorKind::BO_Xor:
+  case BinaryOperatorKind::BO_Or:
+  case BinaryOperatorKind::BO_LAnd:
+  case BinaryOperatorKind::BO_LOr:
+  case BinaryOperatorKind::BO_Comma:
+return true;
+  // Noncommutative operators:
+  case BinaryOperatorKind::BO_Div:
+  case BinaryOperatorKind::BO_Sub:
+  case BinaryOperatorKind::BO_Shl:
+  case BinaryOperatorKind::BO_Shr:
+  case BinaryOperatorKind::BO_Rem:
+  // Member access:
+  case BinaryOperatorKind::BO_PtrMemD:
+  case BinaryOperatorKind::BO_PtrMemI:
+  // Assignment:
+  case BinaryOperatorKind::BO_Assign:
+  case BinaryOperatorKind::BO_MulAssign:
+  case BinaryOperatorKind::BO_DivAssign:
+  case BinaryOperatorKind::BO_RemAssign:
+  case BinaryOperatorKind::BO_AddAssign:
+  case BinaryOperatorKind::BO_SubAssign:
+  case BinaryOperatorKind::BO_ShlAssign:
+  case BinaryOperatorKind::BO_ShrAssign:
+  case BinaryOperatorKind::BO_AndAssign:
+  case BinaryOperatorKind::BO_XorAssign:
+  case BinaryOperatorKind::BO_OrAssign:
+return false;
+  }
+  return false;
+}
+
+/// Some operators are asymmetric and need to be flipped when swapping their
+/// operands
+/// @param[out] Opcode the opcode to potentially swap
+/// If the opcode does not need to be swapped or is not swappable, does nothing
+void swapOperator(BinaryOperatorKind &Opcode) {
+  switch (Opcode) {
+  case BinaryOperatorKind::BO_LT:
+Opcode = BinaryOperatorKind::BO_GT;
+return;
+  case BinaryOperatorKind::BO_GT:
+Opcode = BinaryOperatorKind::BO_LT;
+return;
+  case BinaryOperatorKind::BO_LE:
+Opcode = BinaryOperatorKind::BO_GE;
+return;
+  case BinaryOperatorKind

[clang-tools-extra] [llvm] [clangd] Add CodeAction to swap operands to binary operators (PR #78999)

2024-05-04 Thread Tor Shepherd via cfe-commits

torshepherd wrote:

Ping

https://github.com/llvm/llvm-project/pull/78999
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits