1 /*
2 * Copyright 2019 by its authors. See AUTHORS.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef EOLIAN_CXX_KLASS_DEF_HH
17 #define EOLIAN_CXX_KLASS_DEF_HH
18
19 #include "grammar/type_traits.hpp"
20 #include "grammar/attributes.hpp"
21 #include "grammar/qualifier_def.hpp"
22 #include "grammar/string.hpp"
23 #include "grammar/sequence.hpp"
24 #include "grammar/kleene.hpp"
25 #include "grammar/case.hpp"
26
27 #include <Eolian.h>
28
29 #include <Eina.hh>
30
31 #include <vector>
32 #include <memory>
33 #include <set>
34 #include <iosfwd>
35 #include <string>
36
37 namespace efl { namespace eolian { namespace grammar {
38
39 namespace attributes {
40
41 struct complex_type_def;
42
43 }
44
45 namespace attributes {
46
47 template <typename...Args, std::size_t I>
lexicographical_compare_impl(std::tuple<Args...> const &,std::tuple<Args...> const &,std::integral_constant<std::size_t,I>,std::true_type)48 bool lexicographical_compare_impl(std::tuple<Args...> const&
49 , std::tuple<Args...> const&
50 , std::integral_constant<std::size_t, I>
51 , std::true_type)
52 {
53 return true;
54 }
55 template <typename...Args, std::size_t I>
lexicographical_compare_impl(std::tuple<Args...> const & lhs,std::tuple<Args...> const & rhs,std::integral_constant<std::size_t,I>,std::false_type)56 bool lexicographical_compare_impl(std::tuple<Args...> const& lhs
57 , std::tuple<Args...> const& rhs
58 , std::integral_constant<std::size_t, I>
59 , std::false_type)
60 {
61 return std::get<I>(lhs) < std::get<I>(rhs)
62 || (!(std::get<I>(rhs) < std::get<I>(lhs))
63 && lexicographical_compare_impl(lhs, rhs, std::integral_constant<std::size_t, I+1>()
64 , std::integral_constant<bool, I + 1 == sizeof...(Args)>())
65 )
66 ;
67 }
68 template <typename...Args>
lexicographical_compare(std::tuple<Args...> const & lhs,std::tuple<Args...> const & rhs)69 bool lexicographical_compare(std::tuple<Args...> const& lhs
70 , std::tuple<Args...> const& rhs)
71 {
72 return lexicographical_compare_impl(lhs, rhs, std::integral_constant<std::size_t, 0ul>(), std::false_type());
73 }
74 template <typename T, typename U>
lexicographical_compare(std::tuple<T,U> const & lhs,std::tuple<T,U> const & rhs)75 bool lexicographical_compare(std::tuple<T, U> const& lhs
76 , std::tuple<T, U> const& rhs)
77 {
78 return std::get<0>(lhs) < std::get<0>(rhs)
79 || (!(std::get<0>(rhs) < std::get<0>(lhs))
80 && std::get<1>(lhs) < std::get<1>(rhs));
81 }
82
83 enum class typedecl_type
84 {
85 unknown,
86 struct_,
87 struct_opaque,
88 enum_,
89 alias,
90 function_ptr,
91 };
92
operator <<(std::ostream & s,typedecl_type dec)93 inline std::ostream& operator<<(std::ostream& s, typedecl_type dec)
94 {
95 switch(dec)
96 {
97 case typedecl_type::unknown:
98 return s << "unknown";
99 case typedecl_type::struct_:
100 return s << "struct_";
101 case typedecl_type::struct_opaque:
102 return s << "struct_opaque";
103 case typedecl_type::enum_:
104 return s << "enum_";
105 case typedecl_type::alias:
106 return s << "alias";
107 case typedecl_type::function_ptr:
108 return s << "function_ptr";
109 };
110 return s;
111 }
112
typedecl_type_get(Eolian_Typedecl const * decl)113 inline typedecl_type typedecl_type_get(Eolian_Typedecl const* decl)
114 {
115 if (!decl)
116 return typedecl_type::unknown;
117
118 Eolian_Typedecl_Type t = eolian_typedecl_type_get(decl);
119 switch (t)
120 {
121 case EOLIAN_TYPEDECL_UNKNOWN: return typedecl_type::unknown;
122 case EOLIAN_TYPEDECL_STRUCT: return typedecl_type::struct_;
123 case EOLIAN_TYPEDECL_STRUCT_OPAQUE: return typedecl_type::struct_opaque;
124 case EOLIAN_TYPEDECL_ENUM: return typedecl_type::enum_;
125 case EOLIAN_TYPEDECL_ALIAS: return typedecl_type::alias;
126 case EOLIAN_TYPEDECL_FUNCTION_POINTER: return typedecl_type::function_ptr;
127 default: return typedecl_type::unknown;
128 }
129 }
130
131
132 struct type_def;
133 bool operator==(type_def const& lhs, type_def const& rhs);
134 bool operator!=(type_def const& lhs, type_def const& rhs);
135
136 enum class class_type
137 {
138 regular, abstract_, mixin, interface_
139 };
140
operator <<(std::ostream & s,class_type t)141 inline std::ostream& operator<<(std::ostream& s, class_type t)
142 {
143 switch(t)
144 {
145 case class_type::regular:
146 return s << "regular";
147 case class_type::abstract_:
148 return s << "abstract_";
149 case class_type::mixin:
150 return s << "mixin";
151 case class_type::interface_:
152 return s << "interface_";
153 };
154 return s;
155 }
156
157 struct klass_name
158 {
159 std::vector<std::string> namespaces;
160 std::string eolian_name;
161 qualifier_def base_qualifier;
162 class_type type;
163 std::string klass_get_name;
164 bool is_beta;
165
operator <<(std::ostream & s,klass_name const & name)166 friend inline std::ostream& operator<<(std::ostream& s, klass_name const& name)
167 {
168 s << "[ namespaces: {";
169 std::copy(name.namespaces.begin(), name.namespaces.end(), std::ostream_iterator<std::string>(s, ","));
170 return s << "}, eolian_name: " << name.eolian_name << " base_qualifier: " << name.base_qualifier
171 << " type: " << name.type << " klass_get_name: " << name.klass_get_name << "]";
172 }
173
klass_nameefl::eolian::grammar::attributes::klass_name174 klass_name() {
175 }
176
klass_nameefl::eolian::grammar::attributes::klass_name177 klass_name(std::vector<std::string> namespaces
178 , std::string eolian_name, qualifier_def base_qualifier
179 , class_type type, std::string klass_get_name, bool is_beta)
180 : namespaces(namespaces), eolian_name(eolian_name), base_qualifier(base_qualifier)
181 , type(type), klass_get_name(klass_get_name), is_beta(is_beta) {}
klass_nameefl::eolian::grammar::attributes::klass_name182 klass_name(Eolian_Class const* klass, qualifier_def base_qualifier)
183 : eolian_name( ::eolian_class_short_name_get(klass))
184 , base_qualifier(base_qualifier)
185 , klass_get_name( ::eolian_class_c_get_function_name_get(klass))
186 , is_beta(::eolian_object_is_beta(EOLIAN_OBJECT(klass)))
187 {
188 for(efl::eina::iterator<const char> namespace_iterator ( ::eolian_class_namespaces_get(klass))
189 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
190 {
191 namespaces.push_back(&*namespace_iterator);
192 }
193 switch(eolian_class_type_get(klass))
194 {
195 case EOLIAN_CLASS_REGULAR:
196 type = class_type::regular;
197 break;
198 case EOLIAN_CLASS_ABSTRACT:
199 type = class_type::abstract_;
200 break;
201 case EOLIAN_CLASS_MIXIN:
202 type = class_type::mixin;
203 break;
204 case EOLIAN_CLASS_INTERFACE:
205 type = class_type::interface_;
206 break;
207 default:
208 throw std::runtime_error("Class with unknown type");
209 }
210 }
211 };
212
operator ==(klass_name const & lhs,klass_name const & rhs)213 inline bool operator==(klass_name const& lhs, klass_name const& rhs)
214 {
215 return lhs.namespaces == rhs.namespaces && lhs.eolian_name == rhs.eolian_name
216 && lhs.base_qualifier == rhs.base_qualifier/* && lhs.pointers == rhs.pointers*/;
217 }
operator !=(klass_name const & lhs,klass_name const & rhs)218 inline bool operator!=(klass_name const& lhs, klass_name const& rhs)
219 {
220 return !(lhs == rhs);
221 }
operator <(klass_name const & lhs,klass_name const & rhs)222 inline bool operator<(klass_name const& lhs, klass_name const& rhs)
223 {
224 typedef std::tuple<std::vector<std::string>const&
225 , std::string const&
226 , qualifier_def const&
227 , class_type
228 > tuple_type;
229 return lexicographical_compare(tuple_type(lhs.namespaces, lhs.eolian_name
230 , lhs.base_qualifier
231 , lhs.type)
232 , tuple_type(rhs.namespaces, rhs.eolian_name
233 , rhs.base_qualifier
234 , rhs.type));
235 }
236
237 struct documentation_def
238 {
239 std::string summary;
240 std::string description;
241 std::string since;
242 std::vector<std::string> desc_paragraphs;
243 std::string full_text;
244
245 documentation_def() = default;
documentation_defefl::eolian::grammar::attributes::documentation_def246 documentation_def(std::string summary, std::string description, std::string since, std::string full_text)
247 : summary(summary), description(description), since(since), full_text(full_text)
248 {}
documentation_defefl::eolian::grammar::attributes::documentation_def249 documentation_def(Eolian_Documentation const* eolian_doc)
250 {
251 const char *str;
252
253 if (!eolian_doc)
254 return;
255
256 str = eolian_documentation_summary_get(eolian_doc);
257 if (str)
258 full_text = summary = str;
259
260 str = eolian_documentation_description_get(eolian_doc);
261 if (str) {
262 description = str;
263 // Separate summary from description with a blank line
264 full_text += "\n\n" + description;
265 }
266
267 str = eolian_documentation_since_get(eolian_doc);
268 if (str) {
269 since = str;
270 }
271
272 efl::eina::ptr_list<const char, efl::eina::malloc_clone_allocator>
273 l(eolian_documentation_string_split(description.c_str()));
274 for (auto&& i : l)
275 desc_paragraphs.push_back({&i});
276 }
277
operator ==(documentation_def const & lhs,documentation_def const & rhs)278 friend inline bool operator==(documentation_def const& lhs, documentation_def const& rhs)
279 {
280 return lhs.summary == rhs.summary
281 && lhs.description == rhs.description
282 && lhs.since == rhs.since;
283 }
284 };
285
286 template <>
287 struct tuple_element<0ul, klass_name>
288 {
289 typedef std::vector<std::string> type;
getefl::eolian::grammar::attributes::tuple_element290 static type& get(klass_name& klass) { return klass.namespaces; }
getefl::eolian::grammar::attributes::tuple_element291 static type const& get(klass_name const& klass) { return klass.namespaces; }
292 };
293 template <>
294 struct tuple_element<1ul, klass_name>
295 {
296 typedef std::string type;
getefl::eolian::grammar::attributes::tuple_element297 static type& get(klass_name& klass) { return klass.eolian_name; }
getefl::eolian::grammar::attributes::tuple_element298 static type const& get(klass_name const& klass) { return klass.eolian_name; }
299 };
300 template <int N>
301 struct tuple_element<N, klass_name const> : tuple_element<N, klass_name> {};
302
303 template <int N>
304 typename tuple_element<N, klass_name>::type&
get(klass_name & klass)305 get(klass_name& klass)
306 {
307 return tuple_element<N, klass_name>::get(klass);
308 }
309 template <int N>
310 typename tuple_element<N, klass_name>::type const&
get(klass_name const & klass)311 get(klass_name const& klass)
312 {
313 return tuple_element<N, klass_name>::get(klass);
314 }
315
316 struct regular_type_def
317 {
regular_type_defefl::eolian::grammar::attributes::regular_type_def318 regular_type_def() : type_type(typedecl_type::unknown), is_undefined(false) {}
regular_type_defefl::eolian::grammar::attributes::regular_type_def319 regular_type_def(std::string base_type, qualifier_def qual, std::vector<std::string> namespaces
320 , typedecl_type type_type = typedecl_type::unknown, bool is_undefined = false)
321 : base_type(std::move(base_type)), base_qualifier(qual), namespaces(std::move(namespaces))
322 , type_type(type_type), is_undefined(is_undefined) {}
323
is_typeefl::eolian::grammar::attributes::regular_type_def324 bool is_type(typedecl_type tt) const { return type_type == tt; }
is_unknownefl::eolian::grammar::attributes::regular_type_def325 bool is_unknown() const { return is_type(typedecl_type::unknown); }
is_structefl::eolian::grammar::attributes::regular_type_def326 bool is_struct() const { return is_type(typedecl_type::struct_); }
is_struct_opaqueefl::eolian::grammar::attributes::regular_type_def327 bool is_struct_opaque() const { return is_type(typedecl_type::struct_opaque); }
is_enumefl::eolian::grammar::attributes::regular_type_def328 bool is_enum() const { return is_type(typedecl_type::enum_); }
is_aliasefl::eolian::grammar::attributes::regular_type_def329 bool is_alias() const { return is_type(typedecl_type::alias); }
is_function_ptrefl::eolian::grammar::attributes::regular_type_def330 bool is_function_ptr() const { return is_type(typedecl_type::function_ptr); }
331
operator <<(std::ostream & s,regular_type_def const & def)332 friend inline std::ostream& operator<<(std::ostream& s, regular_type_def const& def)
333 {
334 s << "[ base_type: " << def.base_type << " base_qualifier: " << def.base_qualifier
335 << " namespaces: ";
336 std::copy(def.namespaces.begin(), def.namespaces.end(), std::ostream_iterator<std::string>(s, ", "));
337 return s << " type_type: " << def.type_type << " is_undefined " << def.is_undefined << "]";
338 }
339
340 std::string base_type;
341 qualifier_def base_qualifier;
342 std::vector<std::string> namespaces;
343 typedecl_type type_type;
344 bool is_undefined;
345 };
346
operator ==(regular_type_def const & rhs,regular_type_def const & lhs)347 inline bool operator==(regular_type_def const& rhs, regular_type_def const& lhs)
348 {
349 return rhs.base_type == lhs.base_type && rhs.base_qualifier == lhs.base_qualifier;
350 }
operator !=(regular_type_def const & rhs,regular_type_def const & lhs)351 inline bool operator!=(regular_type_def const& rhs, regular_type_def const& lhs)
352 {
353 return !(rhs == lhs);
354 }
355
356 struct complex_type_def
357 {
358 regular_type_def outer;
359 std::vector<type_def> subtypes;
360
operator <<(std::ostream & s,complex_type_def const & def)361 friend inline std::ostream& operator<<(std::ostream& s, complex_type_def const& def)
362 {
363 s << "[ outer " << def.outer << " subtypes: {";
364 std::copy(def.subtypes.begin(), def.subtypes.end(), std::ostream_iterator<type_def>(s, ", "));
365 return s << "}]";
366 }
367 };
368
operator ==(complex_type_def const & lhs,complex_type_def const & rhs)369 inline bool operator==(complex_type_def const& lhs, complex_type_def const& rhs)
370 {
371 return lhs.outer == rhs.outer && lhs.subtypes == rhs.subtypes;
372 }
operator !=(complex_type_def const & lhs,complex_type_def const & rhs)373 inline bool operator!=(complex_type_def const& lhs, complex_type_def const& rhs)
374 {
375 return !(lhs == rhs);
376 }
377
378 namespace value_ownership
379 {
380 const bool moved = true;
381 const bool unmoved = false;
382 };
383
384 namespace is_by
385 {
386 const bool reference = true;
387 const bool value = false;
388 };
389
390 // type_def represents a type where it is used, like a method parameter or a struc field, in contrast to more
391 // specifict types like struct_def, class_def, function_def, which represents a declaration of a type.
392 struct type_def
393 {
394 typedef eina::variant<klass_name, regular_type_def, complex_type_def> variant_type;
395 variant_type original_type;
396 std::string c_type;
397 bool has_own;
398 bool is_ptr;
399 bool is_beta;
400 std::string doc_summary;
401 bool is_value_type;
402
403 type_def() = default;
type_defefl::eolian::grammar::attributes::type_def404 type_def(variant_type original_type, std::string c_type, bool has_own, bool is_ptr, bool is_beta, std::string doc_summary)
405 : original_type(original_type), c_type(c_type), has_own(has_own), is_ptr(is_ptr), is_beta(is_beta), doc_summary(doc_summary) {}
406
type_defefl::eolian::grammar::attributes::type_def407 type_def(Eolian_Type const* eolian_type, Eolian_Unit const* unit, std::string const& ctype, bool is_moved, bool is_reference)
408 {
409 set(eolian_type, unit, ctype, is_moved, is_reference);
410 }
411 void set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, std::string const & ctype, bool is_moved, bool is_reference);
412 void set(Eolian_Expression_Type eolian_exp_type);
413
operator <(type_def const & lhs,type_def const & rhs)414 friend inline bool operator<(type_def const& lhs, type_def const& rhs)
415 {
416 return lhs.c_type < rhs.c_type;
417 }
operator <<(std::ostream & s,type_def const & rhs)418 friend inline std::ostream& operator<<(std::ostream& s, type_def const& rhs)
419 {
420 return s << "[ original: " << rhs.original_type << " c_type "
421 << rhs.c_type << " has_own " << rhs.has_own << " is_ptr "
422 << rhs.is_ptr << "]";
423 }
424
425 private:
426 void set(const char* regular_name, const char* c_type);
427 };
428
429 struct get_qualifier_visitor
430 {
431 typedef qualifier_def result_type;
432 template <typename T>
operator ()efl::eolian::grammar::attributes::get_qualifier_visitor433 qualifier_def operator()(T const& object) const
434 {
435 return object.base_qualifier;
436 }
operator ()efl::eolian::grammar::attributes::get_qualifier_visitor437 qualifier_def operator()(complex_type_def const& complex) const
438 {
439 return complex.outer.base_qualifier;
440 }
441 };
442
operator ==(type_def const & lhs,type_def const & rhs)443 inline bool operator==(type_def const& lhs, type_def const& rhs)
444 {
445 return lhs.original_type == rhs.original_type && lhs.c_type == rhs.c_type;
446 }
operator !=(type_def const & lhs,type_def const & rhs)447 inline bool operator!=(type_def const& lhs, type_def const& rhs)
448 {
449 return !(lhs == rhs);
450 }
451
452 type_def const void_ {attributes::regular_type_def{"void", {qualifier_info::is_none, {}}, {}}, "void", false, false, false, ""};
453
set(Eolian_Type const * eolian_type,Eolian_Unit const * unit,std::string const & ctype,bool is_moved,bool is_reference)454 inline void type_def::set(Eolian_Type const* eolian_type, Eolian_Unit const* unit, std::string const& ctype, bool is_moved, bool is_reference)
455 {
456 c_type = ctype;
457 is_value_type = ('*' != c_type.back());
458 // ::eina_stringshare_del(stringshare); // this crashes
459 Eolian_Type const* stp = eolian_type_base_type_get(eolian_type);
460 has_own = is_moved;
461
462 is_ptr = is_reference || eolian_type_is_ptr(eolian_type);
463
464 Eolian_Typedecl const* decl = eolian_type_typedecl_get(eolian_type);
465 is_beta = decl && eolian_object_is_beta(EOLIAN_OBJECT(decl));
466 if (decl)
467 {
468 documentation_def documentation = eolian_typedecl_documentation_get(decl);
469 doc_summary = documentation.summary;
470 }
471 switch( ::eolian_type_type_get(eolian_type))
472 {
473 case EOLIAN_TYPE_VOID:
474 original_type = attributes::regular_type_def{"void", {qualifiers(eolian_type, is_moved, is_ptr), {}}, {}};
475 break;
476 case EOLIAN_TYPE_REGULAR:
477 if (!stp)
478 {
479 bool is_undefined = false;
480 Eolian_Typedecl const* decl = eolian_type_typedecl_get(eolian_type);
481 typedecl_type type_type = (decl ? typedecl_type_get(decl) : typedecl_type::unknown);
482 if(decl && eolian_typedecl_type_get(decl) == EOLIAN_TYPEDECL_ALIAS)
483 {
484 Eolian_Type const* aliased = eolian_typedecl_base_type_get(decl);
485 if(aliased && eolian_type_type_get(aliased) == EOLIAN_TYPE_UNDEFINED)
486 {
487 is_undefined = true;
488 }
489 }
490 if(c_type == "va_list *")
491 throw std::runtime_error("");
492 std::vector<std::string> namespaces;
493 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_type_namespaces_get(eolian_type))
494 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
495 namespaces.push_back(&*namespace_iterator);
496 original_type = {regular_type_def{ ::eolian_type_short_name_get(eolian_type), {qualifiers(eolian_type, is_moved, is_ptr), {}}, namespaces, type_type, is_undefined}};
497 }
498 else
499 {
500 complex_type_def complex
501 {{::eolian_type_short_name_get(eolian_type), {qualifiers(eolian_type, is_moved, is_ptr), {}}, {}}, {}};
502 while (stp)
503 {
504 complex.subtypes.push_back({stp
505 , unit
506 , ::eolian_type_c_type_get(stp)
507 , static_cast<bool>(eolian_type_is_move(stp))
508 , is_by::value});
509 stp = eolian_type_next_type_get(stp);
510 }
511 original_type = complex;
512 }
513 break;
514 case EOLIAN_TYPE_CLASS:
515 {
516 Eolian_Class const* klass = eolian_type_class_get(eolian_type);
517 original_type = klass_name(klass, {qualifiers(eolian_type, is_moved, is_ptr), {}});
518 }
519 break;
520 default:
521 throw std::runtime_error("Type not supported");
522 break;
523 }
524 }
525
set(Eolian_Expression_Type eolian_exp_type)526 inline void type_def::set(Eolian_Expression_Type eolian_exp_type)
527 {
528 switch(eolian_exp_type)
529 {
530 case EOLIAN_EXPR_INT:
531 set("int", "int");
532 break;
533 case EOLIAN_EXPR_UINT:
534 set("uint", "unsigned int");
535 break;
536 case EOLIAN_EXPR_FLOAT:
537 set("float", "float");
538 break;
539 case EOLIAN_EXPR_DOUBLE:
540 set("double", "double");
541 break;
542 case EOLIAN_EXPR_STRING:
543 set("string", "const char *");
544 break;
545 case EOLIAN_EXPR_BOOL:
546 set("bool", "Eina_Bool");
547 break;
548 case EOLIAN_EXPR_NULL:
549 set("null", "void *");
550 break;
551 default:
552 // FIXME implement the remaining types
553 EINA_LOG_ERR("Unsupported expression type : %d", eolian_exp_type);
554 std::abort();
555 break;
556 }
557 }
558
set(const char * regular_name,const char * c_type)559 inline void type_def::set(const char* regular_name, const char* c_type)
560 {
561 original_type = attributes::regular_type_def{regular_name, {{}, {}}, {}};
562 this->c_type = c_type;
563 }
564
565 struct alias_def
566 {
567 std::string eolian_name;
568 std::string cxx_name;
569 std::vector<std::string> namespaces;
570 bool is_undefined;
571 type_def base_type {};
572 documentation_def documentation;
573 bool is_beta;
574
alias_defefl::eolian::grammar::attributes::alias_def575 alias_def(Eolian_Typedecl const* alias_obj, Eolian_Unit const* unit)
576 : is_beta(::eolian_typedecl_is_beta(alias_obj))
577 {
578 cxx_name = eolian_name = ::eolian_typedecl_short_name_get(alias_obj);
579
580 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_typedecl_namespaces_get(alias_obj))
581 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
582 {
583 this->namespaces.push_back((&*namespace_iterator));
584 }
585
586 Eolian_Type const* bt = ::eolian_typedecl_base_type_get(alias_obj);
587 if (eolian_type_type_get(bt) == EOLIAN_TYPE_UNDEFINED)
588 is_undefined = true;
589 else
590 {
591 auto eolian_type = ::eolian_typedecl_base_type_get(alias_obj);
592 base_type = type_def(eolian_type
593 , unit
594 , ::eolian_type_c_type_get(eolian_type)
595 , value_ownership::unmoved
596 , is_by::value);
597 is_undefined = false;
598 }
599
600 documentation = ::eolian_typedecl_documentation_get(alias_obj);
601 }
602 };
603
604 enum class parameter_direction
605 {
606 unknown, in, inout, out
607 };
608
609 namespace detail {
610 struct add_optional_qualifier_visitor
611 {
612 typedef void result_type;
613 template <typename T>
operator ()efl::eolian::grammar::attributes::detail::add_optional_qualifier_visitor614 void operator()(T& object) const
615 {
616 object.base_qualifier.qualifier |= qualifier_info::is_optional;
617 }
operator ()efl::eolian::grammar::attributes::detail::add_optional_qualifier_visitor618 void operator()(complex_type_def& complex) const
619 {
620 (*this)(complex.outer);
621 }
622 };
623 }
624
625 struct value_def
626 {
627 typedef eina::variant<int> variant_type; // FIXME support other types
628 variant_type value;
629 std::string literal;
630 type_def type;
631
632 value_def() = default;
value_defefl::eolian::grammar::attributes::value_def633 value_def(Eolian_Value value_obj)
634 {
635 type.set(value_obj.type);
636 value = value_obj.value.i;
637 literal = eolian_expression_value_to_literal(&value_obj);
638 }
639 };
640
641
642 struct expression_def
643 {
644 value_def value;
645 std::string serialized;
646 // We store this explicitly as evaluating the value reduces a name reference
647 // to a plain string value.
648 bool is_name_ref;
649
operator ==(expression_def const & lhs,expression_def const & rhs)650 friend inline bool operator==(expression_def const& lhs, expression_def const& rhs)
651 {
652 return lhs.serialized == rhs.serialized;
653 }
operator !=(expression_def const & lhs,expression_def const & rhs)654 friend inline bool operator!=(expression_def const& lhs, expression_def const& rhs)
655 {
656 return !(lhs == rhs);
657 }
658
expression_defefl::eolian::grammar::attributes::expression_def659 expression_def(Eolian_Expression const* expression) : value(::eolian_expression_eval(expression, EOLIAN_MASK_ALL))
660 , serialized()
661 , is_name_ref(::eolian_expression_type_get(expression) == EOLIAN_EXPR_NAME)
662 {
663 auto serialized_s = ::eolian_expression_serialize(expression);
664 serialized = serialized_s;
665 ::eina_stringshare_del(serialized_s);
666 }
667 };
668
669 struct parameter_def
670 {
671 parameter_direction direction;
672 type_def type;
673 std::string param_name;
674 documentation_def documentation;
675 eina::optional<expression_def> default_value;
676 Eolian_Unit const* unit;
677
operator ==(parameter_def const & lhs,parameter_def const & rhs)678 friend inline bool operator==(parameter_def const& lhs, parameter_def const& rhs)
679 {
680 return lhs.direction == rhs.direction
681 && lhs.type == rhs.type
682 && lhs.param_name == rhs.param_name
683 && lhs.documentation == rhs.documentation
684 && lhs.default_value == rhs.default_value;
685 }
operator !=(parameter_def const & lhs,parameter_def const & rhs)686 friend inline bool operator!=(parameter_def const& lhs, parameter_def const& rhs)
687 {
688 return !(lhs == rhs);
689 }
690
parameter_defefl::eolian::grammar::attributes::parameter_def691 parameter_def(parameter_direction direction, type_def type, std::string param_name,
692 documentation_def documentation, Eolian_Unit const* unit)
693 : direction(std::move(direction)), type(std::move(type)), param_name(std::move(param_name)), documentation(documentation), unit(unit) {}
parameter_defefl::eolian::grammar::attributes::parameter_def694 parameter_def(Eolian_Function_Parameter const* param, Eolian_Unit const* _unit)
695 : type( ::eolian_parameter_type_get(param)
696 , _unit
697 , eolian_parameter_c_type_get(param, EINA_FALSE)
698 , eolian_parameter_is_move(param)
699 , eolian_parameter_is_by_ref(param))
700 , param_name( ::eolian_parameter_name_get(param))
701 , default_value(::eolian_parameter_default_value_get(param) ?
702 ::eolian_parameter_default_value_get(param) :
703 eina::optional<expression_def>{})
704 , unit(_unit)
705 {
706 Eolian_Parameter_Direction direction = ::eolian_parameter_direction_get(param);
707 switch(direction)
708 {
709 case EOLIAN_PARAMETER_UNKNOWN:
710 case EOLIAN_PARAMETER_IN:
711 this->direction = parameter_direction::in;
712 break;
713 case EOLIAN_PARAMETER_INOUT:
714 this->direction = parameter_direction::inout;
715 break;
716 case EOLIAN_PARAMETER_OUT:
717 this->direction = parameter_direction::out;
718 break;
719 }
720 if( ::eolian_parameter_is_optional(param))
721 type.original_type.visit(detail::add_optional_qualifier_visitor{});
722
723 documentation = eolian_parameter_documentation_get(param);
724 }
725 };
726
727 template <>
728 struct tuple_element<0ul, parameter_def>
729 {
730 typedef parameter_direction type;
getefl::eolian::grammar::attributes::tuple_element731 static type const& get(parameter_def const& p) { return p.direction; }
getefl::eolian::grammar::attributes::tuple_element732 static type& get(parameter_def& p) { return p.direction; }
733 };
734 template <>
735 struct tuple_element<1ul, parameter_def>
736 {
737 typedef type_def type;
getefl::eolian::grammar::attributes::tuple_element738 static type const& get(parameter_def const& p) { return p.type; }
getefl::eolian::grammar::attributes::tuple_element739 static type& get(parameter_def& p) { return p.type; }
740 };
741 template <>
742 struct tuple_element<2ul, parameter_def>
743 {
744 typedef std::string type;
getefl::eolian::grammar::attributes::tuple_element745 static type const& get(parameter_def const& p) { return p.param_name; }
getefl::eolian::grammar::attributes::tuple_element746 static type& get(parameter_def& p) { return p.param_name; }
747 };
748 template <>
749 struct tuple_element<3ul, parameter_def>
750 {
751 typedef std::string type;
getefl::eolian::grammar::attributes::tuple_element752 static type const& get(parameter_def const& p) { return p.type.c_type; }
getefl::eolian::grammar::attributes::tuple_element753 static type& get(parameter_def& p) { return p.type.c_type; }
754 };
755 template <int I>
get(parameter_def const & p)756 typename tuple_element<I, parameter_def>::type const& get(parameter_def const& p)
757 { return tuple_element<I, parameter_def>::get(p); }
758 template <int I>
get(parameter_def & p)759 typename tuple_element<I, parameter_def>::type& get(parameter_def& p)
760 { return tuple_element<I, parameter_def>::get(p); }
761
762 enum class function_type
763 {
764 unresolved,
765 property,
766 prop_set,
767 prop_get,
768 method,
769 function_pointer
770 };
771
772 enum class member_scope
773 {
774 scope_unknown,
775 scope_public,
776 scope_private,
777 scope_protected,
778 };
779
780 struct function_def
781 {
782 // Klass information for function_def as method
783 klass_name klass;
784 // Eolian name of the function
785 std::string name;
786
787 // Actual return type as expected in the C version of this function.
788 // For property getters, this could be the type of the single
789 // value it holds
790 type_def return_type;
791 // Parameters of this function as the C implementation of it
792 std::vector<parameter_def> parameters;
793
794 // Original return type as declared in the Eo.
795 type_def explicit_return_type;
796 // Original Eolian keys of this function. Used only for properties
797 std::vector<parameter_def> keys;
798 // Original Eolian values of this function. Used only for properties
799 std::vector<parameter_def> values;
800
801 // Name of this function in the C api
802 std::string c_name;
803 std::string filename;
804 // Namespaces for top-level function pointers
805 std::vector<std::string> namespaces;
806
807 documentation_def documentation;
808 documentation_def return_documentation;
809 documentation_def property_documentation;
810
811 function_type type;
812 member_scope scope;
813 bool is_beta;
814 bool is_protected;
815 bool is_static;
816 Eolian_Unit const* unit;
817
operator ==(function_def const & lhs,function_def const & rhs)818 friend inline bool operator==(function_def const& lhs, function_def const& rhs)
819 {
820 return lhs.klass == rhs.klass
821 && lhs.return_type == rhs.return_type
822 && lhs.name == rhs.name
823 && lhs.parameters == rhs.parameters
824 && lhs.keys == rhs.keys
825 && lhs.values == rhs.values
826 && lhs.c_name == rhs.c_name
827 && lhs.filename == rhs.filename
828 && lhs.namespaces == rhs.namespaces
829 && lhs.documentation == rhs.documentation
830 && lhs.return_documentation == rhs.return_documentation
831 && lhs.property_documentation == rhs.property_documentation
832 && lhs.type == rhs.type
833 && lhs.scope == rhs.scope
834 && lhs.is_beta == rhs.is_beta
835 && lhs.is_protected == rhs.is_protected
836 && lhs.is_static == rhs.is_static;
837 }
operator !=(function_def const & lhs,function_def const & rhs)838 friend inline bool operator!=(function_def const& lhs, function_def const& rhs)
839 {
840 return !(lhs == rhs);
841 }
842 function_def() = default;
843
function_defefl::eolian::grammar::attributes::function_def844 function_def( ::Eolian_Function const* function, Eolian_Function_Type type, Eolian_Typedecl const* tp, Eolian_Unit const* unit)
845 : return_type(void_), explicit_return_type(void_), unit(unit)
846 {
847 Eolian_Type const* r_type = ::eolian_function_return_type_get(function, type);
848 name = ::eolian_function_name_get(function);
849 return_documentation = eolian_function_return_documentation_get(function, type);
850 scope = static_cast<member_scope>(eolian_function_scope_get(function, type));
851
852 if(r_type)
853 {
854 return_type.set(r_type
855 , unit
856 , eolian_function_return_c_type_get(function, type)
857 , eolian_function_return_is_move(function, type)
858 , eolian_function_return_is_by_ref(function, type));
859 explicit_return_type = return_type;
860 }
861
862 if(type == EOLIAN_METHOD || type == EOLIAN_FUNCTION_POINTER)
863 {
864 for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator ( ::eolian_function_parameters_get(function))
865 , param_last; param_iterator != param_last; ++param_iterator)
866 {
867 parameters.push_back({&*param_iterator, unit});
868 }
869 }
870 else if(type == EOLIAN_PROP_GET || type == EOLIAN_PROP_SET)
871 {
872 if(type == EOLIAN_PROP_GET)
873 name += "_get";
874 else
875 name += "_set";
876 for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator
877 ( ::eolian_property_keys_get(function, type))
878 , param_last; param_iterator != param_last; ++param_iterator)
879 {
880 parameter_def param = {&*param_iterator, unit};
881 parameters.push_back(param);
882 keys.push_back(param);
883 }
884 for(efl::eina::iterator<Eolian_Function_Parameter> param_iterator
885 ( ::eolian_property_values_get(function, type))
886 , param_last; param_iterator != param_last; ++param_iterator)
887 {
888 values.push_back({&*param_iterator, unit});
889 }
890
891 if(!r_type && type == EOLIAN_PROP_GET && values.size() == 1)
892 {
893 return_type = values[0].type;
894 if (return_documentation.summary.empty())
895 return_documentation = values[0].documentation;
896
897 }
898 else if(type == EOLIAN_PROP_GET)
899 {
900 for(auto&& v : values)
901 {
902 v.direction = parameter_direction::out;
903 parameters.push_back(v);
904 }
905 }
906 else
907 parameters.insert(parameters.end(), values.begin(), values.end());
908 }
909 c_name = eolian_function_full_c_name_get(function, type);
910 if (type != EOLIAN_FUNCTION_POINTER)
911 {
912 const Eolian_Class *eolian_klass = eolian_function_class_get(function);
913 filename = eolian_object_file_get((const Eolian_Object *)eolian_klass);
914 klass = klass_name(eolian_klass,
915 {attributes::qualifier_info::is_none, std::string()});
916 is_beta = eolian_function_is_beta(function) || klass.is_beta;
917 }
918 else
919 {
920 is_beta = tp && eolian_object_is_beta(EOLIAN_OBJECT(tp));
921 filename = "";
922
923 if (tp)
924 {
925 for (efl::eina::iterator<const char> ns_iterator(::eolian_typedecl_namespaces_get(tp)), ns_last;
926 ns_iterator != ns_last;
927 ns_iterator++)
928 namespaces.push_back(&*ns_iterator);
929 }
930 }
931 is_protected = eolian_function_scope_get(function, type) == EOLIAN_SCOPE_PROTECTED;
932 is_static = eolian_function_is_static(function);
933
934 Eolian_Implement const* implement = eolian_function_implement_get(function);
935 if (!implement)
936 return;
937
938 documentation = eolian_implement_documentation_get(implement, type);
939
940
941 if (type == EOLIAN_PROP_GET || type == EOLIAN_PROP_SET)
942 property_documentation = eolian_implement_documentation_get(implement, EOLIAN_PROPERTY);
943
944 switch (type)
945 {
946 case EOLIAN_UNRESOLVED:
947 this->type = function_type::unresolved;
948 break;
949 case EOLIAN_PROPERTY:
950 this->type = function_type::property;
951 break;
952 case EOLIAN_PROP_GET:
953 this->type = function_type::prop_get;
954 break;
955 case EOLIAN_PROP_SET:
956 this->type = function_type::prop_set;
957 break;
958 case EOLIAN_METHOD:
959 this->type = function_type::method;
960 break;
961 case EOLIAN_FUNCTION_POINTER:
962 this->type = function_type::function_pointer;
963 break;
964 }
965 }
966
template_statementefl::eolian::grammar::attributes::function_def967 std::string template_statement() const
968 {
969 std::string statement;
970 char template_typename = 'F';
971 for (auto const& param : this->parameters)
972 {
973 attributes::regular_type_def const* typ =
974 efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
975 if (typ && typ->is_function_ptr())
976 {
977 char typenam[2] = { 0, };
978 typenam[0] = template_typename++;
979 if (statement.empty())
980 statement = std::string("template <typename ") + typenam;
981 else
982 statement += std::string(", typename ") + typenam;
983 }
984 }
985 if (statement.empty()) return statement;
986 else return statement + ">";
987 }
988
opening_statementsefl::eolian::grammar::attributes::function_def989 std::vector<std::string> opening_statements() const
990 {
991 std::vector<std::string> statements;
992 char template_typename = 'F';
993 for (auto const& param : this->parameters)
994 {
995 attributes::regular_type_def const* typ =
996 efl::eina::get<attributes::regular_type_def>(¶m.type.original_type);
997 if (typ && typ->is_function_ptr())
998 {
999 char typenam[2] = { 0, };
1000 typenam[0] = template_typename++;
1001 std::string statement = "auto fw_" + param.param_name + " = new ::efl::eolian::function_wrapper<";
1002 statement += param.type.c_type + ", " + typenam + ", ::efl::eolian::" + param.type.c_type + "__function_tag>(" + param.param_name + ");";
1003 statements.push_back(statement);
1004 }
1005 }
1006 return statements;
1007 }
1008 };
1009
1010 template <>
1011 struct tuple_element<0ul, function_def>
1012 {
1013 typedef type_def type;
getefl::eolian::grammar::attributes::tuple_element1014 static type& get(function_def& f) { return f.return_type; }
getefl::eolian::grammar::attributes::tuple_element1015 static type const& get(function_def const& f) { return f.return_type; }
1016 };
1017
1018 template <>
1019 struct tuple_element<1ul, function_def>
1020 {
1021 typedef std::string type;
getefl::eolian::grammar::attributes::tuple_element1022 static type& get(function_def& f) { return f.name; }
getefl::eolian::grammar::attributes::tuple_element1023 static type const& get(function_def const& f) { return f.name; }
1024 };
1025
1026 template <>
1027 struct tuple_element<2ul, function_def>
1028 {
1029 typedef std::vector<parameter_def> type;
getefl::eolian::grammar::attributes::tuple_element1030 static type& get(function_def& f) { return f.parameters; }
getefl::eolian::grammar::attributes::tuple_element1031 static type const& get(function_def const& f) { return f.parameters; }
1032 };
1033
1034 struct property_def
1035 {
1036 klass_name klass;
1037 std::string name;
1038 documentation_def documentation;
1039
1040 efl::eina::optional<function_def> getter;
1041 efl::eina::optional<function_def> setter;
1042
operator ==(property_def const & lhs,property_def const & rhs)1043 friend inline bool operator==(property_def const& lhs, property_def const& rhs)
1044 {
1045 return lhs.klass == rhs.klass
1046 && lhs.name == rhs.name
1047 && lhs.documentation == rhs.documentation
1048 && lhs.getter == rhs.getter
1049 && lhs.setter == rhs.setter;
1050 }
1051
operator !=(property_def const & lhs,property_def const & rhs)1052 friend inline bool operator!=(property_def const& lhs, property_def const& rhs)
1053 {
1054 return !(lhs == rhs);
1055 }
1056
1057 property_def() = default;
property_defefl::eolian::grammar::attributes::property_def1058 property_def(Eolian_Function const *function, efl::eina::optional<function_def> getter
1059 , efl::eina::optional<function_def> setter, Eolian_Unit const*)
1060 : getter(getter), setter(setter)
1061 {
1062 name = ::eolian_function_name_get(function);
1063
1064 const Eolian_Class *eolian_klass = eolian_function_class_get(function);
1065 klass = klass_name(eolian_klass, {attributes::qualifier_info::is_none, std::string()});
1066
1067 Eolian_Implement const* implement = ::eolian_function_implement_get(function);
1068 if (!implement)
1069 return;
1070
1071 Eolian_Function_Type type = ::eolian_function_type_get(function);
1072 if (type == EOLIAN_PROP_GET || type == EOLIAN_PROP_SET || type == EOLIAN_PROPERTY)
1073 {
1074 documentation = eolian_implement_documentation_get(implement, EOLIAN_PROPERTY);
1075 // If property-level documentation is empty, use the getter- or setter-level
1076 // docs as fallback (if present).
1077 if (documentation.summary.empty())
1078 documentation = eolian_implement_documentation_get(implement, EOLIAN_PROP_GET);
1079 if (documentation.summary.empty())
1080 documentation = eolian_implement_documentation_get(implement, EOLIAN_PROP_SET);
1081 }
1082 }
1083 };
1084
1085 struct constant_def
1086 {
1087 std::string name;
1088 std::string full_name;
1089 type_def base_type;
1090 documentation_def documentation;
1091 std::vector<std::string> namespaces;
1092 Eolian_Value expression_value;
1093 bool is_extern : 1;
1094
operator ==(constant_def const & lhs,constant_def const & rhs)1095 friend inline bool operator==(constant_def const& lhs, constant_def const& rhs)
1096 {
1097 return lhs.name == rhs.name
1098 && lhs.full_name == rhs.full_name
1099 && lhs.base_type == rhs.base_type
1100 && lhs.documentation == rhs.documentation
1101 && lhs.namespaces == rhs.namespaces
1102 && lhs.expression_value.type == rhs.expression_value.type
1103 && lhs.expression_value.value.ll == rhs.expression_value.value.ll
1104 && lhs.is_extern == rhs.is_extern;
1105 }
1106
operator !=(constant_def const & lhs,constant_def const & rhs)1107 friend inline bool operator!=(constant_def const& lhs, constant_def const& rhs)
1108 {
1109 return !(lhs == rhs);
1110 }
1111
1112 constant_def() = default;
constant_defefl::eolian::grammar::attributes::constant_def1113 constant_def(Eolian_Constant const* constant, Eolian_Unit const* unit)
1114 : name(::eolian_constant_short_name_get(constant))
1115 , full_name(::eolian_constant_name_get(constant))
1116 , base_type(::eolian_constant_type_get(constant)
1117 , unit
1118 , ::eolian_type_c_type_get(eolian_constant_type_get(constant))
1119 , value_ownership::unmoved
1120 , is_by::value)
1121 , documentation(::eolian_constant_documentation_get(constant))
1122 , expression_value()
1123 , is_extern(::eolian_constant_is_extern(constant))
1124 {
1125 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_constant_namespaces_get(constant))
1126 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
1127 {
1128 this->namespaces.push_back((&*namespace_iterator));
1129 }
1130
1131 auto expr = ::eolian_constant_value_get(constant);
1132 if (!expr)
1133 throw std::runtime_error("Could not get constant variable value expression");
1134
1135 this->expression_value = ::eolian_expression_eval(expr, ::EOLIAN_MASK_ALL);
1136 }
1137 };
1138
1139
1140 // template <int N>
1141 // struct tuple_element<N, function_def const> : tuple_element<N, function_def> {};
1142 // template <int N>
1143 // struct tuple_element<N, function_def&> : tuple_element<N, function_def> {};
1144 // template <int N>
1145 // struct tuple_element<N, function_def const&> : tuple_element<N, function_def> {};
1146
1147 // template <std::size_t I>
1148 // typename tuple_element<I, function_def>::type const&
1149 // get(function_def const& f)
1150 // {
1151 // return tuple_element<I, function_def>::get(f);
1152 // }
1153
1154 // template <std::size_t I>
1155 // typename tuple_element<I, function_def>::type&
1156 // get(function_def& f)
1157 // {
1158 // return tuple_element<I, function_def>::get(f);
1159 // }
1160
1161 struct compare_klass_name_by_name
1162 {
operator ()efl::eolian::grammar::attributes::compare_klass_name_by_name1163 bool operator()(klass_name const& lhs, klass_name const& rhs) const
1164 {
1165 return lhs.namespaces < rhs.namespaces
1166 || (!(rhs.namespaces < lhs.namespaces) && lhs.eolian_name < rhs.eolian_name);
1167 }
1168 };
1169
1170 struct event_def
1171 {
1172 klass_name klass;
1173 eina::optional<type_def> type;
1174 std::string name, c_name;
1175 bool is_beta, is_protected;
1176 documentation_def documentation;
1177
operator ==(event_def const & lhs,event_def const & rhs)1178 friend inline bool operator==(event_def const& lhs, event_def const& rhs)
1179 {
1180 return lhs.klass == rhs.klass
1181 && lhs.type == rhs.type
1182 && lhs.name == rhs.name
1183 && lhs.c_name == rhs.c_name
1184 && lhs.is_beta == rhs.is_beta
1185 && lhs.is_protected == rhs.is_protected
1186 && lhs.documentation == rhs.documentation;
1187 }
operator !=(event_def const & lhs,event_def const & rhs)1188 friend inline bool operator!=(event_def const& lhs, event_def const& rhs)
1189 {
1190 return !(lhs == rhs);
1191 }
1192
event_defefl::eolian::grammar::attributes::event_def1193 event_def(klass_name _klass, type_def type, std::string name, std::string c_name,
1194 bool is_beta, bool is_protected, documentation_def documentation)
1195 : klass(_klass), type(type), name(name), c_name(c_name), is_beta(is_beta), is_protected(is_protected)
1196 , documentation(documentation) {}
1197
event_defefl::eolian::grammar::attributes::event_def1198 event_def(Eolian_Event const* event, Eolian_Class const* cls, Eolian_Unit const* unit)
1199 : klass(cls, {attributes::qualifier_info::is_none, std::string()})
1200 , type( ::eolian_event_type_get(event) ? eina::optional<type_def>{{::eolian_event_type_get(event)
1201 , unit
1202 , ::eolian_type_c_type_get(::eolian_event_type_get(event))
1203 , value_ownership::unmoved
1204 , is_by::value}
1205 } : eina::optional<type_def>{})
1206 , name( ::eolian_event_name_get(event))
1207 , c_name( ::eolian_event_c_macro_get(event))
1208 , is_beta( ::eolian_event_is_beta(event) || klass.is_beta)
1209 , is_protected( ::eolian_event_scope_get(event) == EOLIAN_SCOPE_PROTECTED)
1210 , documentation( ::eolian_event_documentation_get(event)) {}
1211 };
1212
1213 template <>
1214 struct tuple_element<0, event_def>
1215 {
1216 typedef eina::optional<type_def> type;
getefl::eolian::grammar::attributes::tuple_element1217 static type& get(event_def& def) { return def.type; }
getefl::eolian::grammar::attributes::tuple_element1218 static type const& get(event_def const& def) { return def.type; }
1219 };
1220 template <>
1221 struct tuple_element<1, event_def>
1222 {
1223 typedef std::string type;
getefl::eolian::grammar::attributes::tuple_element1224 static type& get(event_def& def) { return def.name; }
getefl::eolian::grammar::attributes::tuple_element1225 static type const& get(event_def const& def) { return def.name; }
1226 };
1227 template <>
1228 struct tuple_element<2, event_def>
1229 {
1230 typedef std::string type;
getefl::eolian::grammar::attributes::tuple_element1231 static type& get(event_def& def) { return def.c_name; }
getefl::eolian::grammar::attributes::tuple_element1232 static type const& get(event_def const& def) { return def.c_name; }
1233 };
1234 template <int N>
1235 struct tuple_element<N, event_def const> : tuple_element<N, event_def> {};
1236 template <int N>
get(event_def const & def)1237 auto get(event_def const& def) -> decltype(tuple_element<N, event_def>::get(def))
1238 {
1239 return tuple_element<N, event_def>::get(def);
1240 }
1241 template <int N>
get(event_def & def)1242 auto get(event_def& def) -> decltype(tuple_element<N, event_def>::get(def))
1243 {
1244 return tuple_element<N, event_def>::get(def);
1245 }
1246
1247 struct part_def
1248 {
1249 klass_name klass;
1250 std::string name;
1251 documentation_def documentation;
1252 //bool beta, protect; // can it be applied??
1253
operator ==(part_def const & lhs,part_def const & rhs)1254 friend inline bool operator==(part_def const& lhs, part_def const& rhs)
1255 {
1256 return lhs.klass == rhs.klass
1257 && lhs.name == rhs.name;
1258 }
operator !=(part_def const & lhs,part_def const & rhs)1259 friend inline bool operator!=(part_def const& lhs, part_def const& rhs)
1260 {
1261 return !(lhs == rhs);
1262 }
operator <(part_def const & lhs,part_def const & rhs)1263 friend inline bool operator<(part_def const& lhs, part_def const& rhs)
1264 {
1265 return lhs.name < rhs.name ||
1266 lhs.klass < rhs.klass;
1267 }
1268
part_defefl::eolian::grammar::attributes::part_def1269 part_def(Eolian_Part const* part, Eolian_Unit const*)
1270 : klass(klass_name(::eolian_part_class_get(part), {attributes::qualifier_info::is_none, std::string()}))
1271 , name(::eolian_part_name_get(part))
1272 , documentation(::eolian_part_documentation_get(part)) {}
1273 };
1274
1275 struct constructor_def
1276 {
1277 std::string name;
1278 klass_name klass;
1279 function_def function;
1280 bool is_optional;
1281
operator ==(constructor_def const & lhs,constructor_def const & rhs)1282 friend inline bool operator==(constructor_def const& lhs, constructor_def const& rhs)
1283 {
1284 return lhs.name == rhs.name
1285 && lhs.klass == rhs.klass
1286 && lhs.function == rhs.function
1287 && lhs.is_optional == rhs.is_optional;
1288 }
1289
operator !=(constructor_def const & lhs,constructor_def const & rhs)1290 friend inline bool operator!=(constructor_def const& lhs, constructor_def const& rhs)
1291 {
1292 return !(lhs == rhs);
1293 }
1294
constructor_defefl::eolian::grammar::attributes::constructor_def1295 constructor_def(Eolian_Constructor const* constructor, Eolian_Unit const* unit)
1296 : name(::eolian_constructor_name_get(constructor))
1297 , klass(::eolian_constructor_class_get(constructor), {})
1298 , is_optional(::eolian_constructor_is_optional(constructor))
1299 {
1300 Eolian_Function const* eo_function = ::eolian_constructor_function_get(constructor);
1301 Eolian_Function_Type eo_func_type = ::eolian_function_type_get(eo_function);
1302 if (eo_func_type == ::EOLIAN_PROPERTY)
1303 eo_func_type = ::EOLIAN_PROP_SET;
1304 function = function_def(eo_function, eo_func_type, NULL, unit);
1305 }
1306 };
1307
1308 inline Eolian_Class const* get_klass(klass_name const& klass_name_, Eolian_Unit const* unit);
1309
1310 struct klass_def
1311 {
1312 std::string eolian_name;
1313 std::string cxx_name;
1314 std::string filename;
1315 documentation_def documentation;
1316 std::vector<std::string> namespaces;
1317 std::vector<function_def> functions;
1318 std::vector<property_def> properties;
1319 std::vector<constructor_def> constructors;
1320 std::set<klass_name, compare_klass_name_by_name> inherits;
1321 class_type type;
1322 std::vector<event_def> events;
1323 std::set<klass_name, compare_klass_name_by_name> immediate_inherits;
1324 eina::optional<klass_name> parent;
1325 std::set<klass_name, compare_klass_name_by_name> extensions;
1326 std::string klass_get_name;
1327 bool is_beta;
1328
1329 std::set<part_def> parts;
1330 Eolian_Unit const* unit;
1331
operator ==(klass_def const & lhs,klass_def const & rhs)1332 friend inline bool operator==(klass_def const& lhs, klass_def const& rhs)
1333 {
1334 return lhs.eolian_name == rhs.eolian_name
1335 && lhs.cxx_name == rhs.cxx_name
1336 && lhs.filename == rhs.filename
1337 && lhs.namespaces == rhs.namespaces
1338 && lhs.functions == rhs.functions
1339 && lhs.properties == rhs.properties
1340 && lhs.inherits == rhs.inherits
1341 && lhs.type == rhs.type
1342 && lhs.events == rhs.events
1343 && lhs.parts == rhs.parts
1344 && lhs.klass_get_name == rhs.klass_get_name
1345 && lhs.is_beta == rhs.is_beta;
1346 }
operator !=(klass_def const & lhs,klass_def const & rhs)1347 friend inline bool operator!=(klass_def const& lhs, klass_def const& rhs)
1348 {
1349 return !(lhs == rhs);
1350 }
operator <(klass_def const & lhs,klass_def const & rhs)1351 friend inline bool operator<(klass_def const& lhs, klass_def const& rhs)
1352 {
1353 return lhs.eolian_name < rhs.eolian_name
1354 || lhs.cxx_name < rhs.cxx_name
1355 || lhs.namespaces < rhs.namespaces
1356 || lhs.parts < rhs.parts;
1357 }
1358
operator ==(klass_def const & lhs,klass_name const & rhs)1359 friend inline bool operator==(klass_def const& lhs, klass_name const& rhs)
1360 {
1361 return lhs.namespaces == rhs.namespaces
1362 && lhs.eolian_name == rhs.eolian_name
1363 && lhs.type == rhs.type;
1364 }
operator ==(klass_name const & lhs,klass_def const & rhs)1365 friend inline bool operator==(klass_name const& lhs, klass_def const& rhs)
1366 {
1367 return rhs == lhs;
1368 }
operator !=(klass_def const & lhs,klass_name const & rhs)1369 friend inline bool operator!=(klass_def const& lhs, klass_name const& rhs)
1370 {
1371 return !(lhs == rhs);
1372 }
operator !=(klass_name const & lhs,klass_def const & rhs)1373 friend inline bool operator!=(klass_name const& lhs, klass_def const& rhs)
1374 {
1375 return !(rhs == lhs);
1376 }
1377
1378
klass_defefl::eolian::grammar::attributes::klass_def1379 klass_def(std::string eolian_name, std::string cxx_name, std::string filename
1380 , documentation_def documentation
1381 , std::vector<std::string> namespaces
1382 , std::vector<function_def> functions
1383 , std::vector<property_def> properties
1384 , std::set<klass_name, compare_klass_name_by_name> inherits
1385 , class_type type
1386 , std::set<klass_name, compare_klass_name_by_name> immediate_inherits
1387 , std::string klass_get_name
1388 , bool is_beta
1389 , Eolian_Unit const* unit)
1390 : eolian_name(eolian_name), cxx_name(cxx_name), filename(filename)
1391 , documentation(documentation)
1392 , namespaces(namespaces)
1393 , functions(functions), properties(properties), inherits(inherits), type(type)
1394 , immediate_inherits(immediate_inherits)
1395 , klass_get_name(klass_get_name)
1396 , is_beta(is_beta)
1397 , unit(unit)
1398 {}
klass_defefl::eolian::grammar::attributes::klass_def1399 klass_def(std::string _eolian_name, std::string _cxx_name
1400 , std::vector<std::string> _namespaces
1401 , std::vector<function_def> _functions
1402 , std::vector<property_def> _properties
1403 , std::set<klass_name, compare_klass_name_by_name> _inherits
1404 , class_type _type, Eolian_Unit const* unit
1405 , std::string klass_get_name
1406 , bool is_beta)
1407 : eolian_name(_eolian_name), cxx_name(_cxx_name)
1408 , namespaces(_namespaces)
1409 , functions(_functions), properties(_properties), inherits(_inherits), type(_type)
1410 , klass_get_name(klass_get_name), is_beta(is_beta), unit(unit)
1411 {}
klass_defefl::eolian::grammar::attributes::klass_def1412 klass_def(Eolian_Class const* klass, Eolian_Unit const* unit)
1413 : klass_get_name( ::eolian_class_c_get_function_name_get(klass))
1414 , is_beta(::eolian_class_is_beta(klass))
1415 , unit(unit)
1416 {
1417 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_class_namespaces_get(klass))
1418 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
1419 {
1420 this->namespaces.push_back(&*namespace_iterator);
1421 }
1422 cxx_name = eolian_name = eolian_class_short_name_get(klass);
1423 filename = eolian_object_file_get((const Eolian_Object *)klass);
1424 for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_PROPERTY))
1425 , functions_last; eolian_functions != functions_last; ++eolian_functions)
1426 {
1427 Eolian_Function const* function = &*eolian_functions;
1428 Eolian_Function_Type func_type = ::eolian_function_type_get(function);
1429 if(func_type == EOLIAN_PROPERTY)
1430 {
1431 efl::eina::optional<function_def> getter(nullptr);
1432 efl::eina::optional<function_def> setter(nullptr);
1433 try {
1434 if(::eolian_function_scope_get(function, EOLIAN_PROP_GET) != EOLIAN_SCOPE_PRIVATE)
1435 {
1436 function_def f(function, EOLIAN_PROP_GET, NULL, unit);
1437 functions.push_back(f);
1438 getter = efl::eina::optional<function_def>(f);
1439 }
1440 } catch(std::exception const&) {}
1441 try {
1442 if(::eolian_function_scope_get(function, EOLIAN_PROP_SET) != EOLIAN_SCOPE_PRIVATE)
1443 {
1444 function_def f(function, EOLIAN_PROP_SET, NULL, unit);
1445 functions.push_back(f);
1446 setter = efl::eina::optional<function_def>(f);
1447 }
1448 } catch(std::exception const&) {}
1449 if (getter.is_engaged() || setter.is_engaged())
1450 properties.push_back({function, getter, setter, unit});
1451 }
1452 else
1453 try {
1454 if(::eolian_function_scope_get(function, func_type) != EOLIAN_SCOPE_PRIVATE)
1455 {
1456 efl::eina::optional<function_def> getter(nullptr);
1457 efl::eina::optional<function_def> setter(nullptr);
1458 function_def f(function, func_type, NULL, unit);
1459 if (func_type == EOLIAN_PROP_GET)
1460 getter = efl::eina::optional<function_def>(f);
1461 else if (func_type == EOLIAN_PROP_SET)
1462 setter = efl::eina::optional<function_def>(f);
1463 functions.push_back(f);
1464 if (func_type == EOLIAN_PROP_GET || func_type == EOLIAN_PROP_SET)
1465 properties.push_back({function, getter, setter, unit});
1466 }
1467 } catch(std::exception const&) {}
1468 }
1469 for(efl::eina::iterator<Eolian_Function const> eolian_functions ( ::eolian_class_functions_get(klass, EOLIAN_METHOD))
1470 , functions_last; eolian_functions != functions_last; ++eolian_functions)
1471 {
1472 try {
1473 Eolian_Function const* function = &*eolian_functions;
1474 Eolian_Function_Type func_type = eolian_function_type_get(function);
1475 if(::eolian_function_scope_get(function, func_type) != EOLIAN_SCOPE_PRIVATE)
1476 functions.push_back({function, EOLIAN_METHOD, NULL, unit});
1477 } catch(std::exception const&) {}
1478 }
1479 if(::eolian_class_parent_get(klass))
1480 {
1481 parent = eina::optional<klass_name>({::eolian_class_parent_get(klass), {}});
1482 immediate_inherits.insert(*parent);
1483 }
1484 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_extensions_get(klass))
1485 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
1486 {
1487 Eolian_Class const* inherit = &*inherit_iterator;
1488 klass_name extension(inherit, {});
1489 immediate_inherits.insert(extension);
1490 extensions.insert(extension);
1491 }
1492 std::function<void(Eolian_Class const*)> inherit_algo =
1493 [&] (Eolian_Class const* inherit_klass)
1494 {
1495 if(::eolian_class_parent_get(inherit_klass))
1496 {
1497 Eolian_Class const* inherit = ::eolian_class_parent_get(inherit_klass);
1498 inherits.insert({inherit, {}});
1499 inherit_algo(inherit);
1500 }
1501 for(efl::eina::iterator<Eolian_Class const> inherit_iterator ( ::eolian_class_extensions_get(inherit_klass))
1502 , inherit_last; inherit_iterator != inherit_last; ++inherit_iterator)
1503 {
1504 Eolian_Class const* inherit = &*inherit_iterator;
1505 inherits.insert({inherit, {}});
1506 inherit_algo(inherit);
1507 }
1508 };
1509 inherit_algo(klass);
1510
1511 for(efl::eina::iterator<Eolian_Part const> parts_itr ( ::eolian_class_parts_get(klass))
1512 , parts_last; parts_itr != parts_last; ++parts_itr)
1513 {
1514 parts.insert({&*parts_itr, unit});
1515 }
1516
1517 switch(eolian_class_type_get(klass))
1518 {
1519 case EOLIAN_CLASS_REGULAR:
1520 type = class_type::regular;
1521 break;
1522 case EOLIAN_CLASS_ABSTRACT:
1523 type = class_type::abstract_;
1524 break;
1525 case EOLIAN_CLASS_MIXIN:
1526 type = class_type::mixin;
1527 break;
1528 case EOLIAN_CLASS_INTERFACE:
1529 type = class_type::interface_;
1530 break;
1531 default:
1532 throw std::runtime_error("Class with unknown type");
1533 }
1534 for(efl::eina::iterator<Eolian_Event const> event_iterator( ::eolian_class_events_get(klass))
1535 , event_last; event_iterator != event_last; ++event_iterator)
1536 {
1537 try {
1538 events.push_back({&*event_iterator, klass, unit});
1539 } catch(std::exception const&) {}
1540 }
1541
1542 for(efl::eina::iterator<Eolian_Constructor const> constructor_iterator(::eolian_class_constructors_get(klass))
1543 , constructor_last; constructor_iterator != constructor_last; ++constructor_iterator)
1544 constructors.push_back({&*constructor_iterator, unit});
1545
1546 documentation = eolian_class_documentation_get(klass);
1547 }
1548
1549 // TODO memoize the return?
get_all_methodsefl::eolian::grammar::attributes::klass_def1550 std::vector<function_def> get_all_methods() const
1551 {
1552 std::vector<function_def> ret;
1553
1554 std::copy(functions.cbegin(), functions.cend(), std::back_inserter(ret));
1555
1556 for (auto inherit : inherits)
1557 {
1558 klass_def klass(get_klass(inherit, unit), unit);
1559 std::copy(klass.functions.cbegin(), klass.functions.cend(),
1560 std::back_inserter(ret));
1561 }
1562
1563 return ret;
1564 }
1565
get_all_partsefl::eolian::grammar::attributes::klass_def1566 std::vector<part_def> get_all_parts() const
1567 {
1568 std::vector<part_def> ret;
1569
1570 std::copy(parts.cbegin(), parts.cend(), std::back_inserter(ret));
1571
1572 for (auto inherit : inherits)
1573 {
1574 klass_def klass(get_klass(inherit, unit), unit);
1575 std::copy(klass.parts.cbegin(), klass.parts.cend(),
1576 std::back_inserter(ret));
1577 }
1578
1579 return ret;
1580 }
1581
get_all_eventsefl::eolian::grammar::attributes::klass_def1582 std::vector<event_def> get_all_events() const
1583 {
1584 std::vector<event_def> ret;
1585
1586 std::copy(events.cbegin(), events.cend(), std::back_inserter(ret));
1587
1588 for (auto inherit : inherits)
1589 {
1590 klass_def klass(get_klass(inherit, unit), unit);
1591 std::copy(klass.events.cbegin(), klass.events.cend(),
1592 std::back_inserter(ret));
1593 }
1594
1595 return ret;
1596 }
1597
get_all_constructorsefl::eolian::grammar::attributes::klass_def1598 std::vector<constructor_def> get_all_constructors() const
1599 {
1600 std::vector<constructor_def> ret;
1601
1602 std::copy(constructors.cbegin(), constructors.cend(), std::back_inserter(ret));
1603
1604 for (auto inherit : inherits)
1605 {
1606 klass_def klass(get_klass(inherit, unit), unit);
1607 std::copy(klass.constructors.cbegin(), klass.constructors.cend(),
1608 std::back_inserter(ret));
1609 }
1610
1611 return ret;
1612 }
1613 };
1614
1615 struct enum_value_def
1616 {
1617 value_def value;
1618 std::string name;
1619 std::string c_name;
1620 documentation_def documentation;
1621
enum_value_defefl::eolian::grammar::attributes::enum_value_def1622 enum_value_def(Eolian_Enum_Type_Field const* enum_field, Eolian_Unit const*)
1623 {
1624 name = eolian_typedecl_enum_field_name_get(enum_field);
1625 c_name = eolian_typedecl_enum_field_c_constant_get(enum_field);
1626 auto exp = eolian_typedecl_enum_field_value_get(enum_field, EINA_TRUE);
1627 value = eolian_expression_eval(exp, EOLIAN_MASK_INT); // FIXME hardcoded int
1628 documentation = eolian_typedecl_enum_field_documentation_get(enum_field);
1629 }
1630 };
1631
1632 struct enum_def
1633 {
1634 std::string eolian_name;
1635 std::string cxx_name;
1636 std::vector<std::string> namespaces;
1637 std::vector<enum_value_def> fields;
1638 documentation_def documentation;
1639 bool is_beta;
1640
enum_defefl::eolian::grammar::attributes::enum_def1641 enum_def(Eolian_Typedecl const* enum_obj, Eolian_Unit const* unit)
1642 {
1643 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_typedecl_namespaces_get(enum_obj))
1644 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
1645 {
1646 this->namespaces.push_back((&*namespace_iterator));
1647 }
1648 cxx_name = eolian_name = eolian_typedecl_short_name_get(enum_obj);
1649
1650 for (efl::eina::iterator<const Eolian_Enum_Type_Field> field_iterator(::eolian_typedecl_enum_fields_get(enum_obj))
1651 , field_last; field_iterator != field_last; ++field_iterator)
1652 {
1653 // Fill the types
1654 enum_value_def field_def(&*field_iterator, unit);
1655 this->fields.push_back(field_def);
1656 }
1657 is_beta = eolian_object_is_beta(EOLIAN_OBJECT(enum_obj));
1658
1659 documentation = ::eolian_typedecl_documentation_get(enum_obj);
1660 }
1661 };
1662
1663 struct struct_field_def
1664 {
1665 type_def type;
1666 std::string name;
1667 documentation_def documentation;
1668
struct_field_defefl::eolian::grammar::attributes::struct_field_def1669 struct_field_def(Eolian_Struct_Type_Field const* struct_field, Eolian_Unit const* unit)
1670 {
1671 name = eolian_typedecl_struct_field_name_get(struct_field);
1672 try {
1673 type.set(eolian_typedecl_struct_field_type_get(struct_field)
1674 , unit
1675 , eolian_typedecl_struct_field_c_type_get(struct_field)
1676 , eolian_typedecl_struct_field_is_move(struct_field)
1677 , eolian_typedecl_struct_field_is_by_ref(struct_field));
1678 } catch(std::runtime_error const&) { /* Silently skip pointer fields*/ }
1679 documentation = ::eolian_typedecl_struct_field_documentation_get(struct_field);
1680 }
1681
1682 };
1683
1684 struct struct_def
1685 {
1686 std::string eolian_name;
1687 std::string cxx_name;
1688 std::vector<std::string> namespaces;
1689 std::vector<struct_field_def> fields;
1690 bool is_beta;
1691 documentation_def documentation;
1692
struct_defefl::eolian::grammar::attributes::struct_def1693 struct_def(Eolian_Typedecl const* struct_obj, Eolian_Unit const* unit)
1694 {
1695 for(efl::eina::iterator<const char> namespace_iterator( ::eolian_typedecl_namespaces_get(struct_obj))
1696 , namespace_last; namespace_iterator != namespace_last; ++namespace_iterator)
1697 {
1698 this->namespaces.push_back((&*namespace_iterator));
1699 }
1700 cxx_name = eolian_name = eolian_typedecl_short_name_get(struct_obj);
1701
1702 for(efl::eina::iterator<const Eolian_Struct_Type_Field> field_iterator(::eolian_typedecl_struct_fields_get(struct_obj))
1703 , field_last; field_iterator != field_last; ++field_iterator)
1704 {
1705 struct_field_def field_def(&*field_iterator, unit);
1706 this->fields.push_back(field_def);
1707 }
1708
1709 is_beta = eolian_object_is_beta(EOLIAN_OBJECT(struct_obj));
1710
1711 documentation = ::eolian_typedecl_documentation_get(struct_obj);
1712 }
1713 };
1714
get_klass_name(klass_def const & klass)1715 inline klass_name get_klass_name(klass_def const& klass)
1716 {
1717 return {klass.namespaces, klass.eolian_name, {qualifier_info::is_none, {}}, klass.type, klass.klass_get_name, klass.is_beta};
1718 }
1719
get_klass(klass_name const & klass_name_,Eolian_Unit const * unit)1720 inline Eolian_Class const* get_klass(klass_name const& klass_name_, Eolian_Unit const* unit)
1721 {
1722 std::string klass_name;
1723 if(!as_generator(*(string << ".") << string)
1724 .generate(std::back_insert_iterator<std::string>(klass_name)
1725 , std::make_tuple(klass_name_.namespaces, klass_name_.eolian_name)
1726 , context_null{}))
1727 return nullptr;
1728 else
1729 return ::eolian_unit_class_by_name_get(unit, klass_name.c_str());
1730 }
1731
cpp_namespaces(std::vector<std::string> namespaces)1732 inline std::vector<std::string> cpp_namespaces(std::vector<std::string> namespaces)
1733 {
1734 if(namespaces.empty())
1735 namespaces.push_back("nonamespace");
1736 return namespaces;
1737 }
1738
has_events(klass_def const & klass)1739 inline bool has_events(klass_def const &klass)
1740 {
1741 for (auto&& e : klass.events)
1742 {
1743 (void)e;
1744 return true;
1745 }
1746
1747 for (auto&& c : klass.inherits)
1748 {
1749 attributes::klass_def parent(get_klass(c, klass.unit), klass.unit);
1750 for (auto&& e : parent.events)
1751 {
1752 (void)e;
1753 return true;
1754 }
1755 }
1756
1757 return false;
1758 }
1759
1760 template<typename T>
has_type_return(klass_def const & klass,T visitor)1761 inline bool has_type_return(klass_def const &klass, T visitor)
1762 {
1763 for (auto&& f : klass.functions)
1764 {
1765 if (f.return_type.original_type.visit(visitor))
1766 return true;
1767 }
1768
1769 for (auto&& c : klass.inherits)
1770 {
1771 attributes::klass_def parent(get_klass(c, klass.unit), klass.unit);
1772 if (has_type_return(parent, visitor))
1773 return true;
1774 }
1775
1776 return false;
1777 }
1778
1779 struct string_return_visitor
1780 {
1781 typedef string_return_visitor visitor_type;
1782 typedef bool result_type;
1783 template <typename T>
operator ()efl::eolian::grammar::attributes::string_return_visitor1784 bool operator()(T const&) const { return false; }
operator ()efl::eolian::grammar::attributes::string_return_visitor1785 bool operator()(regular_type_def const& regular) const
1786 {
1787 return regular.base_type == "string";
1788 }
1789 };
1790
1791 struct stringshare_return_visitor
1792 {
1793 typedef stringshare_return_visitor visitor_type;
1794 typedef bool result_type;
1795 template <typename T>
operator ()efl::eolian::grammar::attributes::stringshare_return_visitor1796 bool operator()(T const&) const { return false; }
operator ()efl::eolian::grammar::attributes::stringshare_return_visitor1797 bool operator()(regular_type_def const& regular) const
1798 {
1799 return regular.base_type == "stringshare";
1800 }
1801 };
1802
has_string_return(klass_def const & klass)1803 inline bool has_string_return(klass_def const &klass)
1804 {
1805 return has_type_return(klass, string_return_visitor{});
1806 }
1807
has_stringshare_return(klass_def const & klass)1808 inline bool has_stringshare_return(klass_def const &klass)
1809 {
1810 return has_type_return(klass, stringshare_return_visitor{});
1811 }
1812
1813 }
1814 namespace type_traits {
1815
1816 template <>
1817 struct is_tuple<attributes::parameter_def> : std::true_type {};
1818 template <>
1819 struct is_tuple<attributes::event_def> : std::true_type {};
1820
1821 }
1822
1823 } } }
1824
1825 #endif
1826