1326941Sdim//===--- RefactoringOptionVisitor.h - Clang refactoring library -----------===//
2326941Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6326941Sdim//
7326941Sdim//===----------------------------------------------------------------------===//
8326941Sdim
9326941Sdim#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H
10326941Sdim#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H
11326941Sdim
12326941Sdim#include "clang/Basic/LLVM.h"
13326941Sdim#include <type_traits>
14326941Sdim
15326941Sdimnamespace clang {
16326941Sdimnamespace tooling {
17326941Sdim
18326941Sdimclass RefactoringOption;
19326941Sdim
20326941Sdim/// An interface that declares functions that handle different refactoring
21326941Sdim/// option types.
22326941Sdim///
23326941Sdim/// A valid refactoring option type must have a corresponding \c visit
24326941Sdim/// declaration in this interface.
25326941Sdimclass RefactoringOptionVisitor {
26326941Sdimpublic:
27326941Sdim  virtual ~RefactoringOptionVisitor() {}
28326941Sdim
29326941Sdim  virtual void visit(const RefactoringOption &Opt,
30326941Sdim                     Optional<std::string> &Value) = 0;
31326941Sdim};
32326941Sdim
33326941Sdimnamespace traits {
34326941Sdimnamespace internal {
35326941Sdim
36326941Sdimtemplate <typename T> struct HasHandle {
37326941Sdimprivate:
38326941Sdim  template <typename ClassT>
39326941Sdim  static auto check(ClassT *) -> typename std::is_same<
40326941Sdim      decltype(std::declval<RefactoringOptionVisitor>().visit(
41326941Sdim          std::declval<RefactoringOption>(), *std::declval<Optional<T> *>())),
42326941Sdim      void>::type;
43326941Sdim
44326941Sdim  template <typename> static std::false_type check(...);
45326941Sdim
46326941Sdimpublic:
47326941Sdim  using Type = decltype(check<RefactoringOptionVisitor>(nullptr));
48326941Sdim};
49326941Sdim
50326941Sdim} // end namespace internal
51326941Sdim
52326941Sdim/// A type trait that returns true iff the given type is a type that can be
53326941Sdim/// stored in a refactoring option.
54326941Sdimtemplate <typename T>
55326941Sdimstruct IsValidOptionType : internal::HasHandle<T>::Type {};
56326941Sdim
57326941Sdim} // end namespace traits
58326941Sdim} // end namespace tooling
59326941Sdim} // end namespace clang
60326941Sdim
61326941Sdim#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_VISITOR_H
62