@@ -33,6 +33,17 @@ class TypescriptWriter
3333
3434 void WriteTypeDefiniton (winmd::reader::TypeDef const & type, TextWriter& textWriter)
3535 {
36+ if (!is_type_allowed (settings, type))
37+ return ;
38+
39+ // A couple other types are projected to other JS types
40+ if (type.TypeNamespace () == " Windows.Foundation" sv)
41+ {
42+ auto name = type.TypeName ();
43+ if ((name == " DateTime" sv) || (name == " TimeSpan" sv) || (name == " HResult" sv))
44+ return ;
45+ }
46+
3647 switch (get_category (type))
3748 {
3849 case winmd::reader::category::struct_type:
@@ -85,7 +96,8 @@ class TypescriptWriter
8596
8697 void WriteClassOrInterface (winmd::reader::TypeDef const & type, TextWriter& textWriter)
8798 {
88- if (get_category (type) == winmd::reader::category::interface_type && exclusiveto_class (type))
99+ auto category = winmd::reader::get_category (type);
100+ if ((category == winmd::reader::category::interface_type) && exclusiveto_class (type))
89101 {
90102 return ;
91103 }
@@ -111,13 +123,13 @@ class TypescriptWriter
111123)" );
112124 textWriter.WriteIndentedLine ();
113125 }
114- if (type.Flags ().Abstract () && get_category (type) != winmd::reader::category::interface_type)
126+ if (type.Flags ().Abstract () && (category != winmd::reader::category::interface_type) )
115127 {
116128 textWriter.Write (" abstract " );
117129 }
118130 },
119131 [&]() {
120- switch (get_category (type) )
132+ switch (category )
121133 {
122134 case winmd::reader::category::interface_type:
123135 textWriter.Write (" interface" );
@@ -181,8 +193,7 @@ class TypescriptWriter
181193 {
182194 return ;
183195 }
184- textWriter.Write (
185- get_category (type) == winmd::reader::category::interface_type ? " extends " : " implements " );
196+ textWriter.Write ((category == winmd::reader::category::interface_type) ? " extends " : " implements " );
186197 for (auto && implementsTypeSem : filteredInterfaces)
187198 {
188199 WriteTypeSemantics (implementsTypeSem, type, textWriter, false , false );
@@ -196,7 +207,11 @@ class TypescriptWriter
196207 for (auto && field : type.FieldList ())
197208 {
198209 textWriter.WriteIndentedLine (
199- " % %: " , [&]() { WriteAccess (field.Flags ().Access (), textWriter); },
210+ " %%: " ,
211+ [&]() {
212+ WriteAccess (
213+ field.Flags ().Access (), textWriter, category != winmd::reader::category::class_type);
214+ },
200215 TextWriter::ToCamelCase (std::string (field.Name ())));
201216 WriteTypeSemantics (jswinrt::typeparser::get_type_semantics (field.Signature ().Type ()), type,
202217 textWriter, field.Signature ().Type ().is_szarray (), false );
@@ -206,6 +221,8 @@ class TypescriptWriter
206221 for (auto && prop : type.PropertyList ())
207222 {
208223 textWriter.WriteIndentedLine ();
224+ WriteAccess (prop.MethodSemantic ().first .Method ().Flags ().Access (), textWriter,
225+ category != winmd::reader::category::class_type);
209226 if (prop.MethodSemantic ().first .Method ().Flags ().Static ())
210227 {
211228 textWriter.Write (" static " );
@@ -222,41 +239,28 @@ class TypescriptWriter
222239 }
223240
224241 // Methods:
225- std::map<std::string_view, winmd::reader::MethodDef> eventListeners;
242+ std::vector< winmd::reader::MethodDef> eventListeners;
226243 for (auto && method : type.MethodList ())
227244 {
228245 if (!is_method_allowed (settings, method))
229246 continue ;
230- if (method.SpecialName () &&
231- (starts_with (method.Name (), " get_" ) || starts_with (method.Name (), " put_" )))
232- continue ;
233- if (method.SpecialName () &&
234- (starts_with (method.Name (), " add_" ) || starts_with (method.Name (), " remove_" )))
235- {
236- eventListeners[method.Name ()] = method;
237- }
238- else
247+ else if (!method.SpecialName () || (method.Name () == " .ctor" sv))
239248 {
240249 textWriter.WriteIndentedLine ();
241250 WriteMethod (method, type, textWriter);
242251 }
252+ else if (starts_with (method.Name (), " add_" ))
253+ {
254+ eventListeners.push_back (method);
255+ }
256+ // NOTE: If there's an add there must be a remove and vice-versa
257+ // NOTE: Properties handled later
243258 }
244259
245260 // Event Listeners:
246- for (auto const & [name, method] : eventListeners)
261+ for (auto && method : eventListeners)
247262 {
248- if (!is_method_allowed (settings, method))
249- continue ;
250- textWriter.WriteIndentedLine ();
251- if (name._Starts_with (" add_" ))
252- {
253- WriteEventListener (method, type, textWriter, true );
254- }
255- else
256- {
257- auto addListenerName = " add_" + std::string (method.Name ().substr (7 ));
258- WriteEventListener (eventListeners[addListenerName], type, textWriter, false );
259- }
263+ WriteEventListener (method, type, textWriter);
260264 }
261265
262266 WriteSpecialPropertiesAndMethods (textWriter, type);
@@ -349,29 +353,54 @@ class TypescriptWriter
349353 }
350354
351355 void WriteEventListener (winmd::reader::MethodDef const & addEventListener,
352- winmd::reader::TypeDef const & containerType, TextWriter& textWriter, bool shouldCreateAddListener )
356+ winmd::reader::TypeDef const & containerType, TextWriter& textWriter)
353357 {
354- textWriter.Write (" %EventListener(type: \" %\" , listener: %): void" , shouldCreateAddListener ? " add" : " remove" ,
355- TextWriter::ToCamelCase (TextWriter::ToLowerAllCase (std::string (addEventListener.Name ().substr (4 )))), [&]() {
356- jswinrt::typeparser::method_signature methodSignature (addEventListener);
357- for (auto && [param, paramSignature] : methodSignature.params ())
358- {
359- WriteTypeSemantics (jswinrt::typeparser::get_type_semantics (paramSignature->Type ()), containerType,
360- textWriter, paramSignature->Type ().is_szarray (), false );
361- }
362- });
358+ std::string name{ addEventListener.Name ().substr (4 ) }; // Remove 'add_'
359+ std::transform (
360+ name.begin (), name.end (), name.begin (), [](char ch) { return static_cast <char >(::tolower (ch)); });
361+
362+ auto isClass = winmd::reader::get_category (containerType) == winmd::reader::category::class_type;
363+ const char * accessType = addEventListener.Flags ().Static () ? " static " : " " ;
364+
365+ textWriter.WriteIndentedLine ();
366+ if (isClass)
367+ {
368+ WriteAccess (addEventListener.Flags ().Access (), textWriter, false );
369+ }
370+ textWriter.Write (R"^-^( %addEventListener(type: "%", listener: %): void;)^-^" , accessType, name, [&]() {
371+ jswinrt::typeparser::method_signature methodSignature (addEventListener);
372+ for (auto && [param, paramSignature] : methodSignature.params ())
373+ {
374+ WriteTypeSemantics (jswinrt::typeparser::get_type_semantics (paramSignature->Type ()), containerType,
375+ textWriter, paramSignature->Type ().is_szarray (), false );
376+ }
377+ });
378+
379+ textWriter.WriteIndentedLine ();
380+ if (isClass)
381+ {
382+ WriteAccess (addEventListener.Flags ().Access (), textWriter, false );
383+ }
384+ textWriter.Write (R"^-^( %removeEventListener(type: "%", listener: %): void;)^-^" , accessType, name, [&]() {
385+ jswinrt::typeparser::method_signature methodSignature (addEventListener);
386+ for (auto && [param, paramSignature] : methodSignature.params ())
387+ {
388+ WriteTypeSemantics (jswinrt::typeparser::get_type_semantics (paramSignature->Type ()), containerType,
389+ textWriter, paramSignature->Type ().is_szarray (), false );
390+ }
391+ });
363392 }
364393
365394 void WriteMethod (winmd::reader::MethodDef const & method, winmd::reader::TypeDef const & containerType,
366395 TextWriter& textWriter, bool isAnonymousFunction = false )
367396 {
368397 jswinrt::typeparser::method_signature methodSignature (method);
369398 std::vector<std::pair<std::string_view, winmd::reader::TypeSig>> returnNameTypePairs;
399+ auto isClass = winmd::reader::get_category (containerType) == winmd::reader::category::class_type;
370400 textWriter.Write (
371- " %%%%(%)%;" sv, [&]() { WriteAccess (method.Flags ().Access (), textWriter); },
401+ " %%%%(%)%;" sv, [&]() { WriteAccess (method.Flags ().Access (), textWriter, !isClass ); },
372402 [&]() {
373- if (method.Flags ().Abstract () && !isAnonymousFunction &&
374- get_category (containerType) == winmd::reader::category::class_type)
403+ if (method.Flags ().Abstract () && !isAnonymousFunction && isClass)
375404 {
376405 textWriter.Write (" abstract " );
377406 }
@@ -457,24 +486,38 @@ class TypescriptWriter
457486 if (std::holds_alternative<jswinrt::typeparser::type_definition>(typeSemantics))
458487 {
459488 winmd::reader::TypeDef typeDef = std::get<jswinrt::typeparser::type_definition>(typeSemantics);
460- if (!IsTypeDefAllowed (typeDef))
489+ bool handled = false ;
490+ if (!is_type_allowed (settings, typeDef))
461491 {
462492 textWriter.Write (" any" );
463- return ;
493+ handled = true ;
464494 }
465- if (typeDef.TypeNamespace () == " Windows.Foundation" && typeDef. TypeName () == " HResult " )
495+ else if (typeDef.TypeNamespace () == " Windows.Foundation" sv )
466496 {
467- textWriter.Write (" number" );
468- return ;
497+ auto name = typeDef.TypeName ();
498+ if ((name == " HResult" ) || (name == " TimeSpan" sv))
499+ {
500+ textWriter.Write (" number" );
501+ handled = true ;
502+ }
503+ else if (name == " IAsyncAction" sv)
504+ {
505+ textWriter.Write (" Windows.Foundation.WinRTPromise<void, void>" );
506+ handled = true ;
507+ }
508+ else if (name == " DateTime" sv)
509+ {
510+ textWriter.Write (" Date" );
511+ handled = true ;
512+ }
469513 }
470- if (typeDef. TypeNamespace () == " Windows.Foundation " && typeDef. TypeName () == " IAsyncAction " )
514+ if (!handled )
471515 {
472- textWriter.Write (" Windows.Foundation.WinRTPromise<void, void>" );
473- return ;
516+ textWriter.Write (" %.%" , typeDef.TypeNamespace (), typeDef.TypeName ());
474517 }
518+
475519 bool isStruct = get_category (typeDef) == winmd::reader::category::struct_type;
476- textWriter.Write (" %.%%%" , typeDef.TypeNamespace (), typeDef.TypeName (), isArray ? " []" : " " ,
477- isNullable && !isArray && !isStruct ? " | null" : " " );
520+ textWriter.Write (" %%" , isArray ? " []" : " " , isNullable && !isArray && !isStruct ? " | null" : " " );
478521 }
479522 else if (std::holds_alternative<jswinrt::typeparser::fundamental_type>(typeSemantics))
480523 {
@@ -512,7 +555,7 @@ class TypescriptWriter
512555 else if (std::holds_alternative<jswinrt::typeparser::generic_type_instance>(typeSemantics))
513556 {
514557 auto generic_type_instance = std::get<jswinrt::typeparser::generic_type_instance>(typeSemantics);
515- if (!IsTypeDefAllowed ( generic_type_instance.generic_type ))
558+ if (!is_type_allowed (settings, generic_type_instance.generic_type ))
516559 {
517560 textWriter.Write (" any" );
518561 return ;
@@ -631,11 +674,6 @@ class TypescriptWriter
631674 }
632675 }
633676
634- bool IsTypeDefAllowed (winmd::reader::TypeDef const & type)
635- {
636- return is_type_allowed (settings, type, get_category (type) == winmd::reader::category::class_type);
637- }
638-
639677 static bool IsGeneric (std::string_view name)
640678 {
641679 return name.find (" `" ) != std::string::npos;
0 commit comments