v8toolkit  0.0.1
Utility library for embedding V8 Javascript engine in a c++ program
helper_functions.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <map>
4 #include <vector>
5 #include <string>
6 #include <sstream>
7 #include <iostream>
8 
9 #include "clang.h"
10 
11 #include "annotations.h"
12 
13 
14 
15 extern map<string, string> cpp_to_js_type_conversions;
16 extern vector<string> base_types_to_ignore;
17 
18 class WrappedClass;
19 
20 extern int print_logging;
21 
22 // if a static method has a name matching the key, change it to the value
23 extern map<string, string> static_method_renames;
24 extern map<string, int> template_instantiations;
25 extern vector<string> base_types_to_ignore;
26 extern vector<string> types_to_ignore_regex;
27 extern std::vector<std::string> used_constructor_names;
28 extern int matched_classes_returned;
29 extern vector<string> data_warnings;
30 extern vector<string> data_errors;
32 extern vector<string> never_include_for_any_file;
34 extern vector<string> includes_for_every_class_wrapper_file;
35 bool has_wrapped_class(const CXXRecordDecl * decl);
36 
37 
38 // how was a wrapped class determined to be a wrapped class?
40  FOUND_UNSPECIFIED = 0, // no information on why this class is being wrapped - may change later if more information found
41  FOUND_ANNOTATION, // this class was annotated as being wrapped
42  FOUND_INHERITANCE, // this class is a base of a function that is wrapped
44  FOUND_BASE_CLASS, // if the class is a base class of a wrapped type, the class must be wrapped
46 };
47 
48 
51  EXPORT_NONE, // export nothing
52  EXPORT_SOME, // only exports specifically marked entities
53  EXPORT_EXCEPT, // exports everything except specifically marked entities
54  EXPORT_ALL}; // exports everything
55 
56 EXPORT_TYPE get_export_type(const NamedDecl * decl, EXPORT_TYPE previous = EXPORT_UNSPECIFIED);
57 
58 template<class T>
59 std::string join(const T & source, const std::string & between = ", ", bool leading_between = false);
60 void data_error(const string & error);
61 void data_warning(const string & warning);
62 QualType get_plain_type(QualType qual_type);
63 std::string get_include_for_type_decl(CompilerInstance & compiler_instance, const TypeDecl * type_decl);
64 void print_vector(const vector<string> & vec, const string & header = "", const string & indentation = "", bool ignore_empty = true);
65 std::string get_source_for_source_range(SourceManager & sm, SourceRange source_range);
66 std::string get_source_for_source_range(SourceManager & sm, SourceRange source_range);
68 bool is_good_record_decl(const CXXRecordDecl * decl);
69 std::string get_include_string_for_fileid(CompilerInstance & compiler_instance, FileID & file_id);
71  WrappedClass & wrapped_class,
72  const CXXMethodDecl * method,
73  bool add_leading_comma = false,
74  bool insert_variable_names = false,
75  const string & annotation = "");
76 void update_wrapped_class_for_type(WrappedClass & wrapped_class,
77  QualType qual_type);
78 
79 // takes a file number starting at 1 and incrementing 1 each time
80 // a list of WrappedClasses to print
81 // and whether or not this is the last file to be written
82 void write_classes(int file_count, vector<WrappedClass*> & classes, bool last_one);
83 
84 
85 vector<QualType> get_method_param_qual_types(CompilerInstance & compiler_instance,
86  const CXXMethodDecl * method,
87  string const & annotation = "");
88 
89 vector<string> generate_variable_names(vector<QualType> qual_types, bool with_std_move = false);
90 
91 void print_specialization_info(const CXXRecordDecl * decl);
92 
93 
94 std::string get_type_string(QualType qual_type,
95  const std::string & indentation = "");
96 
97 template<class Callback>
98 void foreach_constructor(const CXXRecordDecl * klass, Callback && callback,
99  const std::string & annotation = "");
100 
102  WrappedClass & wrapped_class,
103  const CXXMethodDecl * method);
104 
105 void generate_javascript_stub(string const &);
106 void generate_bidirectional_classes(CompilerInstance & compiler_instance);
107 void generate_bindings();
108 
109 void data_error(const string & error);
110 void data_warning(const string & warning);
111 
112 
114  bool logging = false;
115 public:
116  PrintLoggingGuard() = default;
118  if (logging) {
119  print_logging--;
120  }
121  }
122  void log(){
123  if (logging == true) {
124  return;
125  }
126  print_logging++;
127  logging = true;
128  }
129 };
130 
131 
132 
133 // joins a range of strings with commas (or whatever specified)
134 template<class T>
135 std::string join(const T & source, const std::string & between, bool leading_between) {
136  if (source.empty()) {
137  return "";
138  }
139  stringstream result;
140  if (leading_between) {
141  result << between;
142  }
143  bool first = true;
144  for (auto & str : source) {
145  if (str == "") {
146  //printf("Skipping blank entry in join()\n");
147  continue;
148  }
149  if (!first) { result << between;}
150  first = false;
151  result << str;
152  }
153  return result.str();
154 }
155 
156 
157 
158 // calls callback for each constructor in the class. If annotation specified, only
159 // constructors with that annotation will be sent to the callback
160 template<class Callback>
161 void foreach_constructor(const CXXRecordDecl * klass, Callback && callback,
162  const std::string & annotation) {
163 
164  if (klass == nullptr) {
165  cerr << fmt::format("Skipping foreach_constructor because decl was nullptr") << endl;
166  return;
167  }
168 
169  string class_name = klass->getNameAsString();
170  if (print_logging) cerr << "Enumerating constructors for " << class_name << " with optional annotation: " << annotation << endl;
171 
172  for(CXXMethodDecl * method : klass->methods()) {
173  CXXConstructorDecl * constructor = dyn_cast<CXXConstructorDecl>(method);
174  bool skip = false;
175  Annotations annotations(method);
176 
177  // check if method is a constructor
178  if (constructor == nullptr) {
179  continue;
180  }
181 
182  if (print_logging) cerr << "Checking constructor: " << endl;
183  if (constructor->getAccess() != AS_public) {
184  if (print_logging) cerr << " Skipping non-public constructor" << endl;
185  skip = true;
186  }
187  if (get_export_type(constructor) == EXPORT_NONE) {
188  if (print_logging) cerr << " Skipping constructor marked for begin skipped" << endl;
189  skip = true;
190  }
191 
192  if (annotation != "" && !annotations.has(annotation)) {
193  if (print_logging) cerr << " Annotation " << annotation << " requested, but constructor doesn't have it" << endl;
194  skip = true;
195  } else {
196  if (skip) {
197  if (print_logging) cerr << " Annotation " << annotation << " found, but constructor skipped for reason(s) listed above" << endl;
198  }
199  }
200 
201 
202  if (skip) {
203  continue;
204  } else {
205  if (print_logging) cerr << " Running callback on constructor" << endl;
206  callback(constructor);
207  }
208  }
209  cerr << fmt::format("Done enumerating constructors for {}", class_name) << endl;
210 }
211 
212 
void print_vector(const vector< string > &vec, const string &header="", const string &indentation="", bool ignore_empty=true)
std::string js_api_header
void update_wrapped_class_for_type(WrappedClass &wrapped_class, QualType qual_type)
string header_for_every_class_wrapper_file
EXPORT_TYPE get_export_type(const NamedDecl *decl, EXPORT_TYPE previous=EXPORT_UNSPECIFIED)
PrintLoggingGuard()=default
void generate_bindings()
FOUND_METHOD
void write_classes(int file_count, vector< WrappedClass * > &classes, bool last_one)
Definition: ast_action.cpp:14
void data_warning(const string &warning)
::std::string string
Definition: gtest-port.h:1097
bool has_wrapped_class(const CXXRecordDecl *decl)
std::string get_type_string(QualType qual_type, const std::string &indentation="")
void generate_javascript_stub(string const &)
vector< string > includes_for_every_class_wrapper_file
std::string get_method_string(CompilerInstance &compiler_instance, WrappedClass &wrapped_class, const CXXMethodDecl *method)
vector< string > data_warnings
EXPORT_TYPE
map< string, string > cpp_to_js_type_conversions
void generate_bidirectional_classes(CompilerInstance &compiler_instance)
QualType get_plain_type(QualType qual_type)
void print_specialization_info(const CXXRecordDecl *decl)
std::string get_canonical_name_for_decl(const TypeDecl *decl)
std::string get_include_string_for_fileid(CompilerInstance &compiler_instance, FileID &file_id)
std::vector< std::string > used_constructor_names
vector< string > base_types_to_ignore
vector< string > data_errors
std::string get_source_for_source_range(SourceManager &sm, SourceRange source_range)
vector< string > types_to_ignore_regex
bool has(const std::string &target) const
Definition: annotations.h:67
int matched_classes_returned
int print_logging
map< string, string > static_method_renames
std::string get_include_for_type_decl(CompilerInstance &compiler_instance, const TypeDecl *type_decl)
CXXRecordDecl const * decl
Definition: wrapped_class.h:31
map< string, int > template_instantiations
std::string join(const T &source, const std::string &between=", ", bool leading_between=false)
CompilerInstance & compiler_instance
Definition: wrapped_class.h:71
vector< string > never_include_for_any_file
void data_error(const string &error)
vector< QualType > get_method_param_qual_types(CompilerInstance &compiler_instance, const CXXMethodDecl *method, string const &annotation="")
std::string get_method_parameters(CompilerInstance &compiler_instance, WrappedClass &wrapped_class, const CXXMethodDecl *method, bool add_leading_comma=false, bool insert_variable_names=false, const string &annotation="")
void foreach_constructor(const CXXRecordDecl *klass, Callback &&callback, const std::string &annotation="")
vector< string > generate_variable_names(vector< QualType > qual_types, bool with_std_move=false)
bool is_good_record_decl(const CXXRecordDecl *decl)