================
@@ -0,0 +1,265 @@
+//===--- InlineConceptRequirement.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/ExprConcepts.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 {
+/// Inlines a concept requirement.
+///
+/// Before:
+///   template <typename T> void f(T) requires foo<T> {}
+///                                            ^^^^^^
+/// After:
+///   template <foo T> void f(T) {}
+class InlineConceptRequirement : public Tweak {
+public:
+  const char *id() const final;
+
+  auto prepare(const Selection &Inputs) -> bool override;
+  auto apply(const Selection &Inputs) -> Expected<Effect> override;
+  auto title() const -> std::string override {
+    return "Inline concept requirement";
+  }
+  auto kind() const -> llvm::StringLiteral override {
+    return CodeAction::REFACTOR_KIND;
+  }
+
+private:
+  const ConceptSpecializationExpr *ConceptSpecializationExpression;
+  const TemplateTypeParmDecl *TemplateTypeParameterDeclaration;
+  const syntax::Token *RequiresToken;
+
+  static auto getTemplateParameterIndexOfTemplateArgument(
+      const TemplateArgument &TemplateArgument) -> std::optional<int>;
+  auto generateRequiresReplacement(ASTContext &)
+      -> llvm::Expected<tooling::Replacement>;
+  auto generateRequiresTokenReplacement(const syntax::TokenBuffer &)
+      -> tooling::Replacement;
+  auto generateTemplateParameterReplacement(ASTContext &Context)
+      -> llvm::Expected<tooling::Replacement>;
+
+  static auto findToken(const ParsedAST *, const SourceRange &,
+                        const tok::TokenKind) -> const syntax::Token *;
+
+  template <typename T, typename NodeKind>
+  static auto findNode(const SelectionTree::Node &Root)
+      -> std::tuple<const T *, const SelectionTree::Node *>;
+
+  template <typename T>
+  static auto findExpression(const SelectionTree::Node &Root)
+      -> std::tuple<const T *, const SelectionTree::Node *> {
+    return findNode<T, Expr>(Root);
+  }
+
+  template <typename T>
+  static auto findDeclaration(const SelectionTree::Node &Root)
+      -> std::tuple<const T *, const SelectionTree::Node *> {
+    return findNode<T, Decl>(Root);
+  }
+};
+
+REGISTER_TWEAK(InlineConceptRequirement)
+
+auto InlineConceptRequirement::prepare(const Selection &Inputs) -> bool {
+  // Check if C++ version is 20 or higher
+  if (!Inputs.AST->getLangOpts().CPlusPlus20)
----------------
timon-ul wrote:

This works exactly only if the user has Cpp20, if they are on Cpp23 this tweak 
will not surface, which I guess is undesired. I do not know the exact check, 
but I assume there is a proper way to figure out if concepts are enabled (or if 
we are at least Cpp20).

https://github.com/llvm/llvm-project/pull/69693
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to