1 #ifndef TYPESCRIPT_API_BASE_H 2 #define TYPESCRIPT_API_BASE_H 5 #include "stringKeyMap.h" 11 template <
class T,
class B>
struct ItemT;
16 template<
class... >
using void_t = void;
18 template <
class T>
struct is_map:
public false_type {};
19 template <
class K,
class V>
struct is_map<
std::map<K,V>>:
public true_type {};
31 template <
class T>
struct is_itemT:
public false_type {};
32 template <
class T,
class B>
struct is_itemT<
minsky::ItemT<T,B>>:
public true_type {};
38 inline typename enable_if<
49 typename enable_if<is_same<T,bool>,
string>::T
53 inline typename enable_if<is_function<T>,
string>::T
88 auto cppName=classdesc::typeName<T>();
90 if (cppName.substr(0,2)==
"::") cppName=cppName.substr(2);
93 auto n=cppName.find(
"minsky::");
100 return cppName.substr(strlen(
"minsky::"));
103 std::replace(cppName.begin(), cppName.end(),
':',
'_');
104 cppName.erase(
std::remove(cppName.begin(), cppName.end(),
' '), cppName.end());
110 typename enable_if<is_enum<T>,
string>::T
114 typename enable_if<is_reference<T>,
string>::T
118 typename enable_if<is_pointer<T>,
string>::T
122 typename enable_if<is_const<T>,std::string>::T
126 typename enable_if<And<is_iterator<T>,Not<is_pointer<T>>>,std::string>::T
137 Not<is_arithmetic<typename T::value_type>>,
138 Not<is_string<typename T::value_type>>
150 Or<is_arithmetic<typename T::value_type>, is_string<typename T::value_type>>
159 is_associative_container<T>,
173 auto k=typescriptType<typename T::key_type>();
174 auto v=typescriptType<typename T::mapped_type>();
175 return "Map<"+k+
","+v+
">";}
192 +typescriptType<typename T::second_type>()+
">";}
196 typename enable_if<is_itemT<T>, std::string>::T
208 namespace typescriptAPI_ns
217 Not<is_container<T>>,
218 Or<Not<is_class<T>>,is_string<T>>
226 And<Not<is_container<T>>, Not<is_string<T>>>
250 is_same<T, StringKeyMap<T>>
258 Property(
const std::string& type={},
const std::string& construction={}):
259 type(type), construction(construction) {}
265 ArgDetail(
const std::string& name={},
const std::string& type={}):
266 name(name), type(type) {}
275 template <
class M,
int N>
278 static void addArgs(std::vector<ArgDetail>& args)
280 constexpr
int i=Arity<M>::value-N+1;
287 static void addArgs(std::vector<ArgDetail>&) {}
315 template <
class C,
class B>
316 typename enable_if<Not<is_map<B>>,
void>::T
319 template <
class C,
class B>
320 typename enable_if<is_map<B>,
void>::T
323 if (typescriptType<C>().substr(0,4)!=
"Map<")
324 t[typescriptType<C>()].super=
"Map<"+typescriptType<typename B::key_type>()+
","+
325 typescriptType<typename B::mapped_type>()+
">";
328 template <
class C,
class B,
class T>
329 typename enable_if<is_arithmetic<T>,
void>::T
332 t[typescriptType<C>()].methods.emplace(tail(d),
typescriptAPI_ns::Method{parameterType<T>(), {{
"...args",typescriptType<T>()+
"[]"}}});
337 template <
class C,
class B,
class T>
338 typename enable_if<is_arithmetic<T>,
void>::T
341 t[typescriptType<C>()].methods.emplace(tail(d),
typescriptAPI_ns::Method{typescriptType<T>(), {{
"...args",typescriptType<T>()+
"[]"}}});
345 std::string
construct(
const std::string& container,
const std::string name)
347 string tn=typescriptType<VT>();
348 return "new "+container+
"(this.$prefix()+'."+name+
"'"+
349 ((is_string<VT>::value || is_enum<VT>::value || is_arithmetic<VT>::value)?
"":
","+tn)+
");";
352 template <
class C,
class B,
class T>
353 typename enable_if<is_sequence<T>,
void>::T
356 auto tn=typescriptType<typename T::value_type>();
357 t[typescriptType<C>()].properties.emplace
359 {
"Sequence<"+tn+
">", construct<typename T::value_type>(
"Sequence<"+tn+
">", tail(d))});
362 template <
class C,
class B,
class T>
363 typename enable_if<is_sequence<T>,
void>::T
365 {typescriptAPI_type<C,B>(t,d,(T*){});}
367 template <
class C,
class B,
class T>
368 typename enable_if<Or<is_same<typename remove_const<T>::type,std::string>,
369 is_enum<typename remove_const<T>::type>>,
void>::T
372 t[typescriptType<C>()].methods.emplace
376 template <
class C,
class B,
class T>
377 typename enable_if<Or<is_same<typename remove_const<T>::type,std::string>,
378 is_enum<typename remove_const<T>::type>>,
void>::T
384 template <
class C,
class B>
386 {typescriptAPI_type<C,B>(t,d,
static_cast<const std::string*
>(
nullptr));}
388 template <
class C,
class B,
class T>
391 string tn=typescriptType<T>();
392 t[typescriptType<C>()].properties.emplace
396 template <
class C,
class B,
class K,
class V>
399 string k=typescriptType<K>();
400 string v=typescriptType<V>();
401 t[typescriptType<C>()].properties.emplace
403 {
"Map<"+k+
","+v+
">", construct<V>(
"Map<"+k+
","+v+
">",tail(d))});
406 template <
class C,
class B,
class V>
409 string v=typescriptType<V>();
410 t[typescriptType<C>()].properties.emplace
414 template <
class C,
class B,
class M>
415 typename enable_if<functional::is_function<M>,
void>::T
418 auto& methods=t[typescriptType<C>()].methods;
419 auto iter=methods.find(typeName<C>());
420 if (iter==methods.end())
422 auto res=methods.emplace
432 auto oldArgs=std::move(res.first->second.args);
435 auto newArgs=res.first->second.args;
437 if (oldArgs!=res.first->second.args)
439 res.first->second.args={{
"...args",
"any[]"}};
441 auto firstArg=!oldArgs.empty()? oldArgs[0]: res.first->second.args[0];
442 if (firstArg.type==
"any[]")
return;
443 if (firstArg.name==
"...args") firstArg.type.erase(firstArg.type.length()-2);
444 for (
auto& i: oldArgs)
445 if (i!=firstArg)
return;
446 for (
auto& i: newArgs)
447 if (i!=firstArg)
return;
448 res.first->second.args={{
"...args",firstArg.type+
"[]"}};
454 template <
class C,
class B,
class T>
459 Not<is_same<typename remove_const<T>::type,std::string>>
468 typescriptAPI<T,T>(t,d);
469 t[typescriptType<C>()].properties.emplace(tail(d), typescriptType<T>());
472 template <
class C,
class B,
class T>
473 typename enable_if<is_excluded<T>,
void>::T
477 template <
class C,
class B,
class T>
482 Not<is_same<typename remove_const<T>::type,std::string>>
488 typescriptAPI<T,T>(t,d);
489 t[typescriptType<C>()].properties.emplace(tail(d), typescriptType<T>());
498 template <
class C,
class B>
501 template <
class C,
class B,
class T>
503 {typescriptAPI_type<C,B>(t,d,a);}
515 {classdesc::typescriptAPI<U,T>(t,d);}
std::map< std::string, Method > methods
Property(const std::string &type={}, const std::string &construction={})
bool operator!=(const ArgDetail &x) const
ArgDetail(const std::string &name={}, const std::string &type={})
enable_if< is_arithmetic< T >, void >::T typescriptAPI_type(typescriptAPI_t &t, const std::string &d, T(B::*))
enable_if< And< is_arithmetic< T >, And< Not< is_const< T > >, Not< is_same< T, bool > > > >, string >::T typescriptTypep()
enable_if< And< Not< is_container< T > >, Or< Not< is_class< T > >, is_string< T > > >, string >::T parameterType()
void typescriptAPI_onbase(typescriptAPI_t &,...)
std::vector< ArgDetail > args
string typescriptType< string >()
void remove(std::vector< T > &x, const V &v)
remove an element from a vector. V must be comparable to a T
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky's state cha...
bool operator==(const ArgDetail &x) const
std::string construct(const std::string &container, const std::string name)
static void addArgs(std::vector< ArgDetail > &)
enable_if< Not< is_map< B > >, void >::T typescriptAPI(typescriptAPI_t &, const std::string &)
static void addArgs(std::vector< ArgDetail > &args)
string typescriptType< void >()
std::map< std::string, Property > properties
string to_string(CONST84 char *x)
void type(classdesc::typescriptAPI_t &t, const std::string &d)