5 * Moonlight List (moonlight-list@lists.ximian.com)
7 * Copyright 2008 Novell, Inc. (http://www.novell.com)
9 * See the LICENSE file included with the distribution for details.
14 using System
.Collections
.Generic
;
20 delegate void output_native_type_delegate (string t
, string k
);
21 static StringBuilder forward_decls
= new StringBuilder ();
22 static StringBuilder cbinding_requisites
= new StringBuilder ();
24 public void Generate ()
26 GlobalInfo info
= GetTypes2 ();
29 GenerateValueH (info
);
33 GenerateTypeStaticCpp (info
);
34 GenerateCBindings (info
);
35 GeneratePInvokes (info
);
36 GenerateTypes_G (info
);
39 GenerateManagedDPs (info
);
40 GenerateManagedDOs (info
);
42 GenerateManagedEvents (info
);
44 GenerateJSBindings (info
);
47 static void GenerateJSBindings (GlobalInfo all
)
49 List
<MethodInfo
> methods
;
50 methods
= all
.JSMethodsToBind
;
51 StringBuilder mappings
= new StringBuilder ();
52 StringBuilder header
= new StringBuilder ();
53 StringBuilder body
= new StringBuilder ();
55 MemberInfo current
= null;
56 Dictionary
<string, List
<MethodInfo
>> types
= new Dictionary
<string, List
<MethodInfo
>> ();
58 foreach (MemberInfo m
in methods
) {
59 MethodInfo method
= (MethodInfo
) m
;
60 string name
= method
.Annotations
.GetValue ("GenerateJSBinding");
63 mappings
.AppendLine ("\tMoonId_" + method
.Parent
.Name
+ "_" + name
+ ",");
65 if (current
!= method
.Parent
) {
66 current
= method
.Parent
;
68 if (!types
.ContainsKey (current
.Name
))
69 types
.Add (current
.Name
, new List
<MethodInfo
>());
70 types
[current
.Name
].Add (method
);
74 foreach (KeyValuePair
<string, List
<MethodInfo
>> t
in types
) {
75 string parent
= t
.Key
;
77 header
.AppendLine ("/*** Moonlight" + parent
+ "Class *********/");
79 header
.AppendLine ("struct Moonlight" + parent
+ "Type : MoonlightDependencyObjectType {");
80 header
.AppendLine ("\tMoonlight" + parent
+ "Type ();");
81 header
.AppendLine ("};");
83 header
.AppendLine ("extern Moonlight" + parent
+ "Type *Moonlight" + parent
+ "Class;");
85 header
.AppendLine ("struct Moonlight" + parent
+ "Object : MoonlightDependencyObjectObject {");
86 header
.AppendLine ("\tMoonlight" + parent
+ "Object (NPP instance) : MoonlightDependencyObjectObject (instance)");
87 header
.AppendLine ("\t{");
88 header
.AppendLine ("\t\tmoonlight_type = Type::" + parent
.ToUpper() + ";");
89 header
.AppendLine ("\t}");
91 header
.AppendLine ("\tvirtual bool Invoke (int id, NPIdentifier name,");
92 header
.AppendLine ("\t\tconst NPVariant *args, guint32 argCount, NPVariant *result);");
94 header
.AppendLine ("};");
96 body
.AppendLine ("/*** Moonlight" + parent
+ "Class *********/");
97 body
.AppendLine ("static NPObject *");
98 body
.AppendLine ("moonlight_" + parent
.ToLower() + "_allocate (NPP instance, NPClass *klass)");
99 body
.AppendLine ("{");
100 body
.AppendLine (" return new Moonlight" + parent
+ "Object (instance);");
101 body
.AppendLine ("}");
103 body
.AppendLine ("static const MoonNameIdMapping moonlight_" + parent
.ToLower() + "_mapping[] = {");
105 for (int i
= 0; i
< t
.Value
.Count
; i
++) {
106 MethodInfo method
= t
.Value
[i
];
107 string name
= method
.Annotations
.GetValue ("GenerateJSBinding");
110 string id
= "MoonId_" + parent
+ "_" + name
;
111 body
.Append (" {\"" + name.ToLower () + "\", " + id + "}");
113 if (i
< t
.Value
.Count
- 1)
115 body
.AppendLine ("");
119 body
.AppendLine ("};");
120 body
.AppendLine ("");
121 body
.AppendLine ("bool");
122 body
.AppendLine ("Moonlight" + parent
+ "Object::Invoke (int id, NPIdentifier name,");
123 body
.AppendLine (" const NPVariant *args, guint32 argCount,");
124 body
.AppendLine (" NPVariant *result)");
125 body
.AppendLine ("{");
126 body
.AppendLine (" " + parent
+ " *dob = (" + parent
+ "*)GetDependencyObject ();");
127 body
.AppendLine ("");
128 body
.AppendLine (" switch (id) {");
130 foreach (MethodInfo method
in t
.Value
) {
131 string name
= method
.Annotations
.GetValue ("GenerateJSBinding");
134 string id
= "MoonId_" + parent
+ "_" + name
;
136 body
.AppendLine ("\t\tcase " + id
+ ": {");
138 bool errorcheck
= false;
139 string argcodes
= "";
140 List
<string> args
= new List
<string>();
141 List
<string> parms
= new List
<string>();
142 for (int i
= 0; i
< method
.Parameters
.Count
; i
++) {
143 ParameterInfo parameter
= method
.Parameters
[i
];
145 if (parameter
.ParameterType
.Value
== "MoonError*") {
148 argcodes
+= parameter
.ParameterType
.GetNPType ();
150 switch (parameter
.ParameterType
.GetNPType ()) {
152 args
.Add ("\t\t\tint arg" + i
+ " = NPVARIANT_TO_INT32 (args[" + i
+ "]);");
153 parms
.Add ("arg" + i
);
156 args
.Add ("\t\t\tchar *arg" + i
+ " = STRDUP_FROM_VARIANT (args[" + i
+ "]);");
157 parms
.Add ("arg" + i
);
160 args
.Add ("\t\t\tNPObject *obj" + i
+ " = NPVARIANT_TO_OBJECT (args[" + i
+ "]);");
161 args
.Add ("\t\t\tif (!npobject_is_dependency_object (obj" + i
+ "))");
162 args
.Add ("\t\t\t\tTHROW_JS_EXCEPTION (\"" + name
+ "\");");
163 args
.Add ("\t\t\tDependencyObject *arg" + i
+ " = ((MoonlightDependencyObjectObject *) obj" + i
+ ")->GetDependencyObject();");
164 parms
.Add ("(" + parameter
.ParameterType
.WriteFormatted () + ") arg" + i
);
167 args
.Add ("\t\t\tdouble arg" + i
+ " = NPVARIANT_TO_DOUBLE (args[" + i
+ "]);");
168 parms
.Add ("arg" + i
);
171 args
.Add ("\t\t\tbool arg" + i
+ " = NPVARIANT_TO_BOOLEAN (args[" + i
+ "]);");
172 parms
.Add ("arg" + i
);
178 if (argcodes
!= "") {
179 body
.AppendLine ("\t\t\tif (!check_arg_list (\"" + argcodes
+ "\", argCount, args))");
180 body
.AppendLine ("\t\t\t\tTHROW_JS_EXCEPTION (\"" + name
+ "\");");
184 body
.AppendLine ("\t\t\tMoonError err;");
189 body
.AppendLine (String
.Join ("\n", args
.ToArray()));
191 body
.Append ("\t\t\t");
193 if (method
.ReturnType
.GetNPType () != "v") {
194 method
.ReturnType
.WriteFormatted (body
);
195 body
.AppendLine (" ret = dob->" + method
.Name
+ "(" + String
.Join (",", parms
.ToArray ()) + ");");
197 body
.AppendLine ("dob->" + method
.Name
+ "(" + String
.Join (",", parms
.ToArray ()) + ");");
199 for (int i
= 0; i
< method
.Parameters
.Count
; i
++) {
200 ParameterInfo parameter
= method
.Parameters
[i
];
201 if (parameter
.ParameterType
.GetNPType () == "s")
202 body
.AppendLine ("g_free (arg" + i
+ ");");
206 body
.AppendLine ("\t\t\tif (err.number != 0) THROW_JS_EXCEPTION (err.message);");
208 switch (method
.ReturnType
.GetNPType ()) {
210 body
.AppendLine ("\t\t\tINT32_TO_NPVARIANT (ret, *result);");
213 body
.AppendLine ("\t\t\tstring_to_npvariant (ret, *result);");
216 body
.AppendLine ("\t\t\tif (ret)");
217 body
.AppendLine ("\t\t\t\tOBJECT_TO_NPVARIANT (EventObjectCreateWrapper (GetPlugin (), ret), *result);");
218 body
.AppendLine ("\t\t\telse");
219 body
.AppendLine ("\t\t\t\tNULL_TO_NPVARIANT (*result);");
222 body
.AppendLine ("\t\t\tDOUBLE_TO_NPVARIANT (ret, *result);");
225 body
.AppendLine ("\t\t\tBOOLEAN_TO_NPVARIANT (ret, *result);");
228 body
.AppendLine ("\t\t\tVOID_TO_NPVARIANT (*result);");
232 body
.AppendLine ("\t\t\treturn true;");
233 body
.AppendLine ("\t\t\tbreak;");
234 body
.AppendLine ("\t\t}");
237 body
.AppendLine ("\t}");
240 body
.AppendLine ("\treturn MoonlightDependencyObjectObject::Invoke (id, name, args, argCount, result);");
241 body
.AppendLine ("}");
244 body
.AppendLine ("Moonlight" + parent
+ "Type::Moonlight" + parent
+ "Type ()");
245 body
.AppendLine ("{");
246 body
.AppendLine (" AddMapping (moonlight_" + parent
.ToLower() + "_mapping, G_N_ELEMENTS (moonlight_" + parent
.ToLower() + "_mapping));");
248 body
.AppendLine (" allocate = moonlight_" + parent
.ToLower() + "_allocate;");
249 body
.AppendLine ("}");
255 string file
= "plugin/plugin-class.h";
257 string contents
= File
.ReadAllText (file
+ ".in");
258 contents
= contents
.Replace ("/*MAP_IDS*/", mappings
.ToString());
259 contents
= contents
.Replace ("/*MAP_HEADERS*/", header
.ToString());
261 StringBuilder text
= new StringBuilder ();
262 Helper
.WriteWarningGenerated (text
);
263 contents
= text
.ToString () + contents
;
264 Helper
.WriteAllText (file
, contents
);
266 file
= "plugin/plugin-class.g.cpp";
267 contents
= File
.ReadAllText (file
+ ".in");
268 contents
= contents
.Replace ("/*MAP_BODY*/", body
.ToString());
270 text
= new StringBuilder ();
271 Helper
.WriteWarningGenerated (text
);
272 contents
= text
.ToString () + contents
;
273 Helper
.WriteAllText (file
, contents
);
276 static void GenerateManagedEvents (GlobalInfo all
)
278 string base_dir
= Environment
.CurrentDirectory
;
279 string class_dir
= Path
.Combine (base_dir
, "class");
280 string sys_win_dir
= Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), "System.Windows");
281 string filename
= Path
.Combine (sys_win_dir
, "Events.g.cs");
282 string previous_namespace
= "";
283 List
<TypeInfo
> sorted_types
= new List
<TypeInfo
> ();
284 StringBuilder text
= new StringBuilder ();
285 Dictionary
<TypeInfo
, List
<FieldInfo
>> types
= new Dictionary
<TypeInfo
,List
<FieldInfo
>> ();
287 foreach (FieldInfo field
in all
.Events
) {
288 TypeInfo parent
= field
.Parent
as TypeInfo
;
289 List
<FieldInfo
> fields
;
290 string managed_parent
= field
.Annotations
.GetValue ("ManagedDeclaringType");
292 if (!field
.IsEvent
|| !field
.GenerateManagedEvent
)
295 if (managed_parent
!= null) {
296 parent
= all
.Children
[managed_parent
] as TypeInfo
;
299 throw new Exception (string.Format ("Could not find the type '{0}' set as ManagedDeclaringType of '{1}'", managed_parent
, field
.FullName
));
303 throw new Exception (string.Format ("The field '{0}' does not have its parent set.", field
.FullName
));
305 if (!types
.TryGetValue (parent
, out fields
)) {
306 fields
= new List
<FieldInfo
> ();
307 types
.Add (parent
, fields
);
308 sorted_types
.Add (parent
);
313 Helper
.WriteWarningGenerated (text
);
314 text
.AppendLine ("using Mono;");
315 text
.AppendLine ("using System;");
316 text
.AppendLine ("using System.Collections.Generic;");
317 text
.AppendLine ("using System.Windows;");
318 text
.AppendLine ("using System.Windows.Controls;");
319 text
.AppendLine ("using System.Windows.Documents;");
320 text
.AppendLine ("using System.Windows.Ink;");
321 text
.AppendLine ("using System.Windows.Input;");
322 text
.AppendLine ("using System.Windows.Markup;");
323 text
.AppendLine ("using System.Windows.Media;");
324 text
.AppendLine ("using System.Windows.Media.Animation;");
325 text
.AppendLine ("using System.Windows.Shapes;");
328 text
.AppendLine ("namespace Mono {");
329 text
.AppendLine ("\tinternal static class EventIds {");
330 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
331 if (t
.GetEventCount () == 0)
335 foreach (FieldInfo field
in t
.Events
) {
336 text
.Append ("\t\tpublic const int ");
337 text
.Append (t
.Name
);
339 text
.Append (field
.EventName
);
340 text
.Append ("Event = ");
341 text
.Append (t
.GetEventId (field
));
342 text
.AppendLine (";");
345 text
.AppendLine ("\t}");
347 text
.AppendLine ("\tinternal static partial class Events {");
348 text
.AppendLine ("\t\tpublic static UnmanagedEventHandler CreateDispatcherFromEventId (int eventId, Delegate value) {");
349 text
.AppendLine ("\t\t\tswitch (eventId) {");
351 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
352 if (t
.GetEventCount () == 0)
356 foreach (FieldInfo field
in t
.Events
) {
357 if (field
.GenerateManagedEventField
== false)
359 text
.Append ("\t\t\t\tcase EventIds.");
360 text
.Append (t
.Name
);
362 text
.Append (field
.EventName
);
363 text
.Append ("Event: return Events.");
365 text
.Append (GetDispatcherMethodName(field
.EventDelegateType
));
367 text
.Append (field
.EventDelegateType
);
368 text
.Append (") value)");
369 text
.AppendLine (";");
372 text
.AppendLine ("\t\t\t\tdefault: throw new NotSupportedException ();");
373 text
.AppendLine ("\t\t\t}");
374 text
.AppendLine ("\t\t}");
375 text
.AppendLine ("\t}");
377 text
.AppendLine ("}");
379 sorted_types
.Sort (new Members
.MembersSortedByManagedFullName
<TypeInfo
> ());
380 for (int i
= 0; i
< sorted_types
.Count
; i
++) {
381 TypeInfo type
= sorted_types
[i
];
382 List
<FieldInfo
> fields
= types
[type
];
383 TypeInfo parent
= type
;
386 ns
= parent
.Namespace
;
388 if (string.IsNullOrEmpty (ns
)) {
389 Console
.WriteLine ("The type '{0}' in {1} does not have a namespace annotation.", parent
.FullName
, parent
.Header
);
393 if (type
.Annotations
.ContainsKey ("ManagedEvents")) {
394 string event_mode
= type
.Annotations
.GetValue ("ManagedEvents");
395 switch (event_mode
) {
402 throw new Exception (string.Format ("Invalid value '{0}' for ManagedEvents in '{1}'", event_mode
, type
.FullName
));
407 Console
.WriteLine ("'{0}''s Namespace = 'None', this type should have set @ManagedEvents=Manual to not create events.", type
.FullName
);
411 string check_ns
= Path
.Combine (Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), ns
), parent
.Name
+ ".cs");
412 if (!File
.Exists (check_ns
))
413 Console
.WriteLine ("The file {0} does not exist, did you annotate the class with the wrong namespace?", check_ns
);
415 if (previous_namespace
!= ns
) {
416 if (previous_namespace
!= string.Empty
) {
417 text
.AppendLine ("}");
420 text
.Append ("namespace ");
422 text
.AppendLine (" {");
423 previous_namespace
= ns
;
427 text
.Append ("\tpartial class ");
428 text
.Append (parent
.ManagedName
);
429 text
.AppendLine (" {");
431 fields
.Sort (new Members
.MembersSortedByName
<FieldInfo
> ());
434 foreach (FieldInfo field
in fields
) {
441 text
.Append ("\t\t");
442 Helper
.WriteAccess (text
, field
.GetManagedAccessorAccess ());
443 text
.Append (" event ");
444 text
.Append (field
.EventDelegateType
);
446 text
.Append (field
.EventName
);
447 text
.AppendLine (" {");
450 text
.Append ("\t\t\t");
451 if (field
.GetManagedAccessorAccess () != field
.GetManagedGetterAccess ()) {
452 Helper
.WriteAccess (text
, field
.GetManagedGetterAccess ());
456 text
.Append ("add { RegisterEvent (EventIds.");
457 text
.Append (field
.ParentType
.Name
);
459 text
.Append (field
.EventName
);
460 text
.Append ("Event, value, Events.");
461 text
.Append (GetDispatcherMethodName(field
.EventDelegateType
));
462 text
.Append (" (value)");
463 text
.AppendLine ("); }");
465 text
.Append ("\t\t\t");
466 text
.Append ("remove { UnregisterEvent (EventIds.");
467 text
.Append (field
.ParentType
.Name
);
469 text
.Append (field
.EventName
);
470 text
.Append ("Event, value);");
471 text
.AppendLine (" }");
473 text
.AppendLine ("\t\t}");
475 if (field
.GenerateManagedEventField
) {
476 text
.Append ("\t\t");
477 text
.Append (string.Format ("public static readonly RoutedEvent {0}Event = new RoutedEvent (EventIds.{1}_{2}Event);", field
.EventName
, field
.ParentType
.Name
, field
.EventName
));
482 text
.AppendLine ("\t}");
485 text
.AppendLine ("}");
487 Helper
.WriteAllText (filename
, text
.ToString ());
490 static string GetDispatcherMethodName (string delegateType
)
492 if (delegateType
.Contains ("<")) {
493 string[] delegate_types
= delegateType
.Split ('<', '>');
494 return string.Format ("Create{0}{1}Dispatcher", delegate_types
[1], delegate_types
[0]);
497 return string.Format ("Create{0}Dispatcher", delegateType
);
500 static void GenerateManagedDOs (GlobalInfo all
)
502 string base_dir
= Environment
.CurrentDirectory
;
503 string class_dir
= Path
.Combine (base_dir
, "class");
504 string sys_win_dir
= Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), "System.Windows");
505 string filename
= Path
.Combine (sys_win_dir
, "DependencyObject.g.cs");
506 string previous_namespace
= "";
507 StringBuilder text
= new StringBuilder ();
508 List
<TypeInfo
> types
= all
.GetDependencyObjects ();
510 Helper
.WriteWarningGenerated (text
);
511 text
.AppendLine ("using Mono;");
512 text
.AppendLine ("using System;");
513 text
.AppendLine ("using System.Collections.Generic;");
514 text
.AppendLine ("using System.Windows;");
515 text
.AppendLine ("using System.Windows.Controls;");
516 text
.AppendLine ("using System.Windows.Documents;");
517 text
.AppendLine ("using System.Windows.Ink;");
518 text
.AppendLine ("using System.Windows.Input;");
519 text
.AppendLine ("using System.Windows.Markup;");
520 text
.AppendLine ("using System.Windows.Media;");
521 text
.AppendLine ("using System.Windows.Media3D;");
522 text
.AppendLine ("using System.Windows.Media.Animation;");
523 text
.AppendLine ("using System.Windows.Shapes;");
526 for (int i
= 0; i
< types
.Count
; i
++) {
527 TypeInfo type
= types
[i
];
528 bool call_initialize
= type
.Annotations
.ContainsKey ("CallInitialize");
533 if (string.IsNullOrEmpty (ns
)) {
534 Console
.WriteLine ("The type '{0}' in {1} does not have a namespace annotation.", type
.FullName
, Path
.GetFileName (type
.Header
));
539 //Console.WriteLine ("The type '{0}''s Namespace annotation is 'None'.", type.FullName);
543 string check_ns
= Path
.Combine (Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), ns
), type
.ManagedName
.Replace ("`1", "") + ".cs");
544 if (!File
.Exists (check_ns
)) {
545 Console
.WriteLine ("The file {0} does not exist, did you annotate the class with the wrong namespace?", check_ns
);
549 if (previous_namespace
!= ns
) {
550 if (previous_namespace
!= string.Empty
) {
551 text
.AppendLine ("}");
554 text
.Append ("namespace ");
556 text
.AppendLine (" {");
557 previous_namespace
= ns
;
562 if (type
.ContentProperty
!= null)
563 text
.AppendFormat ("\t[ContentProperty (\"{0}\")]\n", type
.ContentProperty
);
564 text
.Append ("\tpartial class ");
565 text
.Append (type
.ManagedName
.Replace ("`1", "<T>"));
566 text
.AppendLine (" {");
569 if (!string.IsNullOrEmpty (type
.C_Constructor
)) {
570 string access
= "Public";
571 foreach (MemberInfo member
in type
.Children
.Values
) {
572 MethodInfo method
= member
as MethodInfo
;
574 if (method
== null || !method
.IsConstructor
|| method
.IsStatic
)
577 if (method
.Parameters
.Count
!= 0)
580 if (method
.Annotations
.ContainsKey ("ManagedAccess"))
581 access
= method
.Annotations
.GetValue ("ManagedAccess");
586 text
.Append ("\t\t");
587 Helper
.WriteAccess (text
, access
);
589 text
.Append (type
.ManagedName
.Replace ("`1", ""));
590 text
.Append (" () : base (NativeMethods.");
591 text
.Append (type
.C_Constructor
);
592 text
.Append (" (), true)");
593 if (call_initialize
) {
595 text
.AppendLine ("\t\t{");
596 text
.AppendLine ("\t\t\tInitialize ();");
597 text
.AppendLine ("\t\t}");
599 text
.AppendLine (" {}");
604 text
.Append ("\t\tinternal ");
605 text
.Append (type
.ManagedName
.Replace ("`1", ""));
606 text
.Append (" (IntPtr raw, bool dropref) : base (raw, dropref)");
607 if (call_initialize
) {
609 text
.AppendLine ("\t\t{");
610 text
.AppendLine ("\t\t\tInitialize ();");
611 text
.AppendLine ("\t\t}");
613 text
.AppendLine (" {}");
616 text
.AppendLine ("\t}");
618 text
.AppendLine ("}");
620 Helper
.WriteAllText (filename
, text
.ToString ());
623 static void GenerateManagedDPs (GlobalInfo all
)
625 string base_dir
= Environment
.CurrentDirectory
;
626 string class_dir
= Path
.Combine (base_dir
, "class");
627 string sys_win_dir
= Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), "System.Windows");
628 string filename
= Path
.Combine (sys_win_dir
, "DependencyProperty.g.cs");
629 string previous_namespace
= "";
630 List
<TypeInfo
> sorted_types
= new List
<TypeInfo
> ();
631 StringBuilder text
= new StringBuilder ();
632 Dictionary
<TypeInfo
, List
<FieldInfo
>> types
= new Dictionary
<TypeInfo
,List
<FieldInfo
>> ();
634 foreach (FieldInfo field
in all
.DependencyProperties
) {
635 TypeInfo parent
= field
.Parent
as TypeInfo
;
636 List
<FieldInfo
> fields
;
637 string managed_parent
= field
.Annotations
.GetValue ("ManagedDeclaringType");
639 if (field
.Annotations
.GetValue ("GenerateManagedDP") == "false")
642 if (managed_parent
!= null) {
643 parent
= all
.Children
[managed_parent
] as TypeInfo
;
646 throw new Exception (string.Format ("Could not find the type '{0}' set as ManagedDeclaringType of '{1}'", managed_parent
, field
.FullName
));
650 throw new Exception (string.Format ("The field '{0}' does not have its parent set.", field
.FullName
));
652 if (!types
.TryGetValue (parent
, out fields
)) {
653 fields
= new List
<FieldInfo
> ();
654 types
.Add (parent
, fields
);
655 sorted_types
.Add (parent
);
660 Helper
.WriteWarningGenerated (text
);
661 text
.AppendLine ("using Mono;");
662 text
.AppendLine ("using System;");
663 text
.AppendLine ("using System.Collections.Generic;");
664 text
.AppendLine ("using System.Windows;");
665 text
.AppendLine ("using System.Windows.Controls;");
666 text
.AppendLine ("using System.Windows.Documents;");
667 text
.AppendLine ("using System.Windows.Ink;");
668 text
.AppendLine ("using System.Windows.Input;");
669 text
.AppendLine ("using System.Windows.Markup;");
670 text
.AppendLine ("using System.Windows.Media;");
671 text
.AppendLine ("using System.Windows.Media3D;");
672 text
.AppendLine ("using System.Windows.Media.Animation;");
673 text
.AppendLine ("using System.Windows.Media.Effects;");
674 text
.AppendLine ("using System.Windows.Shapes;");
677 sorted_types
.Sort (new Members
.MembersSortedByManagedFullName
<TypeInfo
> ());
678 for (int i
= 0; i
< sorted_types
.Count
; i
++) {
679 TypeInfo type
= sorted_types
[i
];
680 List
<FieldInfo
> fields
= types
[type
];
681 TypeInfo parent
= type
;
684 ns
= parent
.Namespace
;
686 if (string.IsNullOrEmpty (ns
)) {
687 Console
.WriteLine ("The type '{0}' in {1} does not have a namespace annotation.", parent
.FullName
, parent
.Header
);
691 if (type
.Annotations
.ContainsKey ("ManagedDependencyProperties")) {
692 string dp_mode
= type
.Annotations
.GetValue ("ManagedDependencyProperties");
700 throw new Exception (string.Format ("Invalid value '{0}' for ManagedDependencyProperties in '{1}'", dp_mode
, type
.FullName
));
705 Console
.WriteLine ("'{0}''s Namespace = 'None', this type should have set @ManagedDependencyProperties=Manual to not create DPs.", type
.FullName
);
709 string check_ns
= Path
.Combine (Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), ns
), parent
.Name
+ ".cs");
710 if (!File
.Exists (check_ns
))
711 Console
.WriteLine ("The file {0} does not exist, did you annotate the class with the wrong namespace?", check_ns
);
713 if (previous_namespace
!= ns
) {
714 if (previous_namespace
!= string.Empty
) {
715 text
.AppendLine ("}");
718 text
.Append ("namespace ");
720 text
.AppendLine (" {");
721 previous_namespace
= ns
;
725 text
.Append ("\tpartial class ");
726 text
.Append (parent
.ManagedName
);
727 text
.AppendLine (" {");
729 fields
.Sort (new Members
.MembersSortedByName
<FieldInfo
> ());
731 // The DP registration
732 foreach (FieldInfo field
in fields
) {
733 bool conv_int_to_double
= field
.GetDPManagedPropertyType (all
) == "int" && field
.GetDPPropertyType (all
).Name
== "double";
735 text
.Append ("\t\t");
736 Helper
.WriteAccess (text
, field
.GetManagedFieldAccess ());
737 text
.Append (" static readonly DependencyProperty ");
738 text
.Append (field
.Name
);
739 text
.Append (" = DependencyProperty.Lookup (Kind.");
740 text
.Append (field
.ParentType
.KindName
);
741 text
.Append (", \"");
742 text
.Append (field
.GetDependencyPropertyName ());
743 text
.Append ("\", typeof (");
744 if (conv_int_to_double
)
745 text
.Append ("double");
747 text
.Append (field
.GetDPManagedPropertyType (all
));
748 text
.AppendLine ("));");
751 foreach (FieldInfo field
in fields
) {
752 bool conv_int_to_double
= field
.GetDPManagedPropertyType (all
) == "int" && field
.GetDPPropertyType (all
).Name
== "double";
754 if (field
.IsDPAttached
|| !field
.GenerateManagedAccessors
)
760 text
.Append ("\t\t");
761 Helper
.WriteAccess (text
, field
.GetManagedAccessorAccess ());
763 text
.Append (field
.GetDPManagedPropertyType (all
));
765 text
.Append (field
.GetDependencyPropertyName ());
766 text
.AppendLine (" {");
769 text
.Append ("\t\t\t");
770 if (field
.GetManagedAccessorAccess () != field
.GetManagedGetterAccess ()) {
771 Helper
.WriteAccess (text
, field
.GetManagedGetterAccess ());
775 text
.Append ("get { return (");
776 text
.Append (field
.GetDPManagedPropertyType (all
));
777 if (conv_int_to_double
)
778 text
.Append (") (double");
779 text
.Append (") GetValue (");
780 text
.Append (field
.Name
);
781 text
.AppendLine ("); }");
784 if (!field
.IsDPReadOnly
) {
785 text
.Append ("\t\t\t");
786 if (field
.GetManagedAccessorAccess () != field
.GetManagedSetterAccess ()) {
787 Helper
.WriteAccess (text
, field
.GetManagedSetterAccess ());
790 text
.Append ("set { SetValue (");
791 text
.Append (field
.Name
);
792 text
.AppendLine (", value); }");
794 text
.AppendLine ("\t\t}");
797 text
.AppendLine ("\t}");
799 text
.AppendLine ("}");
801 Helper
.WriteAllText (filename
, text
.ToString ());
804 class TypeEdgeCount
{
805 public TypeEdgeCount (TypeInfo type
)
808 Inbound
= new List
<TypeInfo
>();
809 Outbound
= new List
<TypeInfo
>();
812 public TypeInfo Type
{
815 public List
<TypeInfo
> Inbound
{
818 public List
<TypeInfo
> Outbound
{
823 static List
<FieldInfo
> TopoSortedProperties (GlobalInfo all
, List
<TypeInfo
> types
)
825 Dictionary
<TypeInfo
,TypeEdgeCount
> typeHash
= new Dictionary
<TypeInfo
,TypeEdgeCount
>();
827 List
<TypeInfo
> remainingTypes
= new List
<TypeInfo
>();
829 foreach (TypeInfo type
in types
) {
830 typeHash
.Add (type
, new TypeEdgeCount (type
));
831 remainingTypes
.Add (type
);
834 // build up edges for our graph
835 foreach (TypeInfo type
in typeHash
.Keys
) {
837 // every property defines an edge from the declaring type to the property type
838 foreach (FieldInfo prop
in type
.Properties
) {
839 if (string.IsNullOrEmpty (prop
.DPDefaultValue
))
842 TypeInfo propType
= prop
.GetDPPropertyType (all
);
843 if (propType
== type
)
845 if (typeHash
.ContainsKey (propType
) && !typeHash
[propType
].Inbound
.Contains (type
)) {
846 typeHash
[propType
].Inbound
.Add (type
);
847 typeHash
[type
].Outbound
.Add (propType
);
851 // every base class has an edge to subclass
852 // (this is kind of a hack to deal with
853 // property types which are listed as base
854 // types when the default values are
857 TypeInfo ourType
= type
;
858 TypeReference baseRef
= ourType
.Base
;
859 while (baseRef
!= null && !string.IsNullOrEmpty (baseRef
.Value
)) {
860 TypeInfo baseType
= (TypeInfo
) all
.Children
[baseRef
.Value
];
861 if (baseType
== null)
863 if (typeHash
.ContainsKey (baseType
) && !typeHash
[baseType
].Outbound
.Contains (ourType
)) {
864 typeHash
[baseType
].Outbound
.Add (ourType
);
865 typeHash
[ourType
].Inbound
.Add (baseType
);
868 if (!typeHash
.ContainsKey (ourType
))
870 baseRef
= ourType
.Base
;
874 List
<TypeInfo
> sorted
= new List
<TypeInfo
>();
875 List
<TypeInfo
> roots
= new List
<TypeInfo
>();
877 foreach (TypeEdgeCount tec
in typeHash
.Values
) {
878 if (tec
.Inbound
.Count
== 0)
879 roots
.Add (tec
.Type
);
882 while (roots
.Count
> 0) {
883 TypeInfo type
= roots
[0];
887 remainingTypes
.Remove (type
);
889 foreach (TypeInfo targetType
in typeHash
[type
].Outbound
) {
890 if (!typeHash
.ContainsKey (targetType
))
892 typeHash
[targetType
].Inbound
.Remove (type
);
893 if (typeHash
[targetType
].Inbound
.Count
== 0) {
894 roots
.Add (targetType
);
899 if (remainingTypes
.Count
> 0) {
900 throw new Exception (string.Format ("cycle in the DO/DP graph ({0} types left)", remainingTypes
.Count
));
903 List
<FieldInfo
> fields
= new List
<FieldInfo
>();
904 foreach (TypeInfo type
in sorted
) {
905 foreach (FieldInfo field
in type
.Properties
)
906 fields
.Insert (0, field
);
911 static void GenerateDPs (GlobalInfo all
)
913 string base_dir
= Environment
.CurrentDirectory
;
914 string moon_dir
= Path
.Combine (base_dir
, "src");
915 // int version_previous = 0;
916 StringBuilder text
= new StringBuilder ();
917 List
<FieldInfo
> fields
= all
.DependencyProperties
;
918 List
<string> headers
= new List
<string> ();
920 List
<TypeInfo
> types
= new List
<TypeInfo
> ();
921 foreach (FieldInfo field
in fields
) {
922 if (!types
.Contains ((TypeInfo
)field
.Parent
))
923 types
.Add ((TypeInfo
)field
.Parent
);
925 fields
= TopoSortedProperties (all
, types
);
927 headers
.Add ("dependencyproperty.h");
928 headers
.Add ("validators.h");
929 headers
.Add ("provider.h");
930 headers
.Add ("color.h");
931 headers
.Add ("managedtypeinfo.h");
932 foreach (FieldInfo field
in fields
) {
934 if (string.IsNullOrEmpty (field
.Header
))
936 h
= Path
.GetFileName (field
.Header
);
938 if (!headers
.Contains (h
))
942 Helper
.WriteWarningGenerated (text
);
944 text
.AppendLine ("#include <config.h>");
947 foreach (string h
in headers
) {
948 text
.Append ("#include \"");
950 text
.AppendLine ("\"");
953 text
.AppendLine ("void");
954 text
.AppendLine ("Types::RegisterNativeProperties ()");
955 text
.AppendLine ("{");
957 for (int i
= 0; i
< fields
.Count
; i
++) {
958 FieldInfo field
= fields
[i
];
959 TypeInfo type
= field
.ParentType
;
960 TypeInfo propertyType
= null;
961 string default_value
= field
.DPDefaultValue
;
962 bool has_default_value
= !string.IsNullOrEmpty (default_value
);
963 string autocreator
= field
.DPAutoCreator
;
964 bool is_nullable
= field
.IsDPNullable
;
965 bool is_attached
= field
.IsDPAttached
;
966 bool is_readonly
= field
.IsDPReadOnly
;
967 bool is_always_change
= field
.IsDPAlwaysChange
;
968 string validator
= field
.DPValidator
;
969 bool is_full
= is_attached
|| is_readonly
|| is_always_change
|| validator
!= null || autocreator
!= null || is_nullable
;
971 propertyType
= field
.GetDPPropertyType (all
);
975 if (propertyType
== null) {
976 text
.Append ("// (no PropertyType was found for this DependencyProperty) ");
978 headers
.Add (propertyType
.Header
);
981 text
.Append ("DependencyProperty::Register");
983 text
.Append ("Full");
986 text
.Append ("this, ");
987 text
.Append ("Type::");
988 text
.Append (type
.KindName
);
989 text
.Append (", \"");
991 text
.Append (field
.GetDependencyPropertyName ());
995 text
.Append (field
.IsCustom
? "true" : "false");
999 if (has_default_value
) {
1000 if (default_value
.StartsWith ("new "))
1001 text
.Append ("Value::CreateUnrefPtr (");
1003 text
.Append ("new Value (");
1004 text
.Append (default_value
);
1007 text
.Append ("NULL");
1010 if (has_default_value
) {
1011 if (default_value
.StartsWith ("new "))
1012 text
.Append ("Value::CreateUnrefPtr (");
1014 text
.Append ("new Value (");
1015 text
.Append (default_value
);
1020 if ((has_default_value
|| is_full
))
1023 if (propertyType
!= null) {
1024 if (propertyType
.IsEnum
) {
1025 text
.Append ("Type::INT32");
1027 text
.Append ("Type::");
1028 text
.Append (propertyType
.KindName
);
1030 } else if (!has_default_value
) {
1031 text
.Append ("Type::INVALID");
1032 Console
.WriteLine ("{0} does not define its property type.", field
.FullName
);
1037 text
.Append (is_attached
? "true" : "false");
1039 text
.Append (is_readonly
? "true" : "false");
1041 text
.Append (is_always_change
? "true" : "false");
1043 text
.Append ("NULL");
1045 text
.Append (validator
!= null ? ("Validators::" + validator
) : "NULL");
1047 text
.Append (autocreator
!= null
1048 ? (autocreator
.Contains("::") ? autocreator
: "AutoCreators::" + autocreator
)
1051 text
.Append (is_nullable
? "true" : "false");
1054 text
.AppendLine (");");
1056 text
.AppendLine ("}");
1059 // Static initializers
1060 for (int i
= 0; i
< fields
.Count
; i
++) {
1061 FieldInfo field
= fields
[i
];
1062 text
.Append ("const int ");
1063 text
.Append (field
.Parent
.Name
);
1065 text
.Append (field
.Name
);
1066 text
.Append (" = ");
1068 text
.AppendLine (";");
1073 for (int i
= 0; i
< fields
.Count
; i
++) {
1074 FieldInfo field
= fields
[i
];
1076 string prop_type_str
;
1078 string prop_default
= null;
1079 bool both
= field
.Annotations
.ContainsKey ("GenerateAccessors");
1080 bool setter
= both
|| field
.Annotations
.ContainsKey ("GenerateSetter");
1081 bool getter
= both
|| field
.Annotations
.ContainsKey ("GenerateGetter");
1082 bool is_attached
= field
.IsDPAttached
;
1083 bool nullable_setter
= setter
&& field
.IsDPNullable
;
1084 bool doing_nullable_setter
= false;
1086 if (!setter
&& !getter
)
1089 prop_type
= field
.GetDPPropertyType (all
);
1091 switch (prop_type
.Name
) {
1093 prop_type_str
= "const char *";
1094 value_str
= "String";
1098 value_str
= "Int32";
1099 prop_type_str
= prop_type
.Name
;
1103 value_str
= "Double";
1104 prop_type_str
= prop_type
.Name
;
1105 prop_default
= "0.0";
1108 prop_type_str
= prop_type
.Name
;
1110 prop_default
= "false";
1113 prop_type_str
= "gunichar";
1118 prop_type_str
= "Value *";
1119 prop_default
= "NULL";
1123 prop_type_str
= prop_type
.Name
;
1124 value_str
= prop_type
.Name
;
1128 string GetterName
= string.Format ("{0}::Get{1}", field
.ParentType
.Name
, field
.GetDependencyPropertyName());
1129 string SetterName
= string.Format ("{0}::Set{1}", field
.ParentType
.Name
, field
.GetDependencyPropertyName());
1132 text
.Append (prop_type_str
);
1133 if (field
.IsDPNullable
|| (prop_type
.IsClass
|| prop_type
.IsStruct
))
1136 text
.Append (GetterName
);
1138 text
.AppendLine (" (DependencyObject *obj)");
1140 text
.AppendLine (" ()");
1141 text
.AppendLine ("{");
1144 if (value_str
== null) {
1145 text
.Append ("\treturn ");
1146 } else if (is_attached
) {
1147 text
.Append ("\tValue *value = (!obj) ? NULL : ");
1149 text
.Append ("\tValue *value = ");
1152 text
.AppendFormat ("{0}{1}GetValue ({2}::{3});\n",
1153 is_attached
? "obj->" : "",
1154 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1155 field
.ParentType
.Name
, field
.Name
);
1158 text
.AppendFormat ("\tif (!value) value = Deployment::GetCurrent ()->GetTypes ()->GetProperty ({0}::{1})->GetDefaultValue();\n",
1159 field
.ParentType
.Name
, field
.Name
);
1162 if (value_str
== null) {
1164 } else if (field
.IsDPNullable
|| (prop_type
.IsClass
|| prop_type
.IsStruct
|| prop_type
.Name
== "char*")) {
1165 text
.Append ("\treturn value ? ");
1166 if (prop_type
.IsEnum
) {
1167 text
.AppendFormat ("({0}) value->AsInt32() : ({0}) 0", prop_type
.Name
);
1169 if (!field
.IsDPNullable
&& (/*prop_type.IsStruct || */prop_default
!= null))
1170 if (string.IsNullOrEmpty (prop_default
))
1171 throw new NotImplementedException (
1172 string.Format ("Generation of DependencyProperties with struct values ({0}.{1})",
1173 field
.ParentType
.Name
, field
.Name
));
1175 text
.AppendFormat ("value->As{0}{1} () : {2}",
1176 field
.IsDPNullable
&& !(prop_type
.IsStruct
|| prop_type
.IsClass
) ? "Nullable" : "",
1178 !field
.IsDPNullable
&& prop_default
!= null ? prop_default
: "NULL");
1181 // Value cannot be null, so don't need to check for it
1182 text
.Append ("\treturn ");
1183 if (prop_type
.IsEnum
) {
1184 text
.AppendFormat ("({0}) value->AsInt32 ()", prop_type
.Name
);
1186 text
.AppendFormat ("value->As{0} ()", value_str
);
1190 if (value_str
!= null)
1191 text
.AppendLine (";");
1192 text
.AppendLine ("}");
1198 text
.AppendLine ("void");
1199 text
.Append (SetterName
);
1202 text
.Append ("DependencyObject *obj, ");
1203 text
.Append (prop_type_str
);
1204 if (prop_type
.Name
!= "char*")
1206 if (!nullable_setter
&& (prop_type
.IsClass
|| prop_type
.IsStruct
))
1208 text
.AppendLine ("value)");
1210 text
.AppendLine ("{");
1212 text
.AppendLine ("\tif (!obj) return;");
1213 if (doing_nullable_setter
) {
1214 text
.AppendLine ("\tif (!value)");
1215 text
.Append ("\t\t");
1216 text
.AppendFormat ("{0}{1}SetValue ({2}::{3}, NULL);\n",
1217 is_attached
? "obj->" : "",
1218 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1219 field
.ParentType
.Name
, field
.Name
);
1220 text
.AppendLine ("\telse");
1221 text
.Append ("\t\t");
1222 text
.AppendFormat ("{0}{1}SetValue ({2}::{3}, Value (*value));\n",
1223 is_attached
? "obj->" : "",
1224 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1225 field
.ParentType
.Name
, field
.Name
);
1227 if (!nullable_setter
&& prop_type
.IsStruct
)
1228 text
.AppendLine ("\tif (!value) return;");
1230 text
.AppendFormat ("{0}{1}SetValue ({2}::{3}, ",
1231 is_attached
? "obj->" : "",
1232 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1233 field
.ParentType
.Name
, field
.Name
);
1235 if (prop_type
.Name
== "guint64" || prop_type
.Name
== "TimeSpan") {
1236 text
.AppendFormat ("Value (value, Type::{0}));\n",
1237 prop_type
.KindName
);
1239 else if (prop_type
.Name
== "char") {
1240 text
.AppendLine ("Value (value, Type::CHAR));");
1242 else if ((value_str
== null) || (!nullable_setter
&& prop_type
.IsStruct
)) {
1243 text
.AppendLine ("Value (*value));");
1245 else if (prop_type
.IsClass
) {
1246 text
.AppendLine ("Value::CreateUnrefPtr (value));");
1249 text
.AppendLine ("Value (value));");
1252 text
.AppendLine ("}");
1256 if (nullable_setter
) {
1257 if (!prop_type
.IsStruct
)
1258 prop_type_str
+= " *";
1259 nullable_setter
= false;
1260 doing_nullable_setter
= true;
1261 goto do_nullable_setter
;
1265 Helper
.WriteAllText (Path
.Combine (moon_dir
, "dependencyproperty.g.cpp"), text
.ToString ());
1269 static GlobalInfo
GetTypes2 ()
1271 string srcdir
= Path
.Combine (Environment
.CurrentDirectory
, "src");
1272 string asfdir
= Path
.Combine (srcdir
, "asf");
1273 string plugindir
= Path
.Combine (Environment
.CurrentDirectory
, "plugin");
1274 List
<string> all_files
= new List
<string> ();
1276 all_files
.AddRange (Directory
.GetFiles (srcdir
, "*.h"));
1277 all_files
.AddRange (Directory
.GetFiles (asfdir
, "*.h"));
1278 all_files
.AddRange (Directory
.GetFiles (plugindir
, "*.h"));
1280 RemoveExcludedSrcFiles (srcdir
, all_files
);
1282 Tokenizer tokenizer
= new Tokenizer (all_files
.ToArray ());
1283 GlobalInfo all
= new GlobalInfo ();
1285 tokenizer
.Advance (false);
1288 while (ParseMembers (all
, tokenizer
)) {
1290 } catch (Exception ex
) {
1291 throw new Exception (string.Format ("{0}({1}): {2}", tokenizer
.CurrentFile
, tokenizer
.CurrentLine
, ex
.Message
), ex
);
1294 // Add all the manual types
1296 TypeInfo IComparableInfo
;
1297 TypeInfo IFormattableInfo
;
1298 TypeInfo IConvertibleInfo
;
1299 TypeInfo IEquatableBoolInfo
;
1300 TypeInfo IComparableBoolInfo
;
1301 TypeInfo IEquatableDoubleInfo
;
1302 TypeInfo IComparableDoubleInfo
;
1303 TypeInfo IEquatableFloatInfo
;
1304 TypeInfo IComparableFloatInfo
;
1305 TypeInfo IEquatableCharInfo
;
1306 TypeInfo IComparableCharInfo
;
1307 TypeInfo IEquatableIntInfo
;
1308 TypeInfo IComparableIntInfo
;
1309 TypeInfo IEquatableLongInfo
;
1310 TypeInfo IComparableLongInfo
;
1311 TypeInfo IEquatableStringInfo
;
1312 TypeInfo IComparableStringInfo
;
1313 TypeInfo IEquatableTimeSpanInfo
;
1314 TypeInfo IComparableTimeSpanInfo
;
1315 TypeInfo IEquatableUintInfo
;
1316 TypeInfo IComparableUintInfo
;
1317 TypeInfo IEquatableUlongInfo
;
1318 TypeInfo IComparableUlongInfo
;
1320 all
.Children
.Add (new TypeInfo ("object", "OBJECT", "INVALID", true, true));
1322 all
.Children
.Add (IComparableInfo
= new TypeInfo ("IComparable", "ICOMPARABLE", "OBJECT", true, true, false, true));
1323 all
.Children
.Add (IFormattableInfo
= new TypeInfo ("IFormattable", "IFORMATTABLE", "OBJECT", true, true, false, true));
1324 all
.Children
.Add (IConvertibleInfo
= new TypeInfo ("IConvertible", "ICONVERTIBLE", "OBJECT", true, true, false, true));
1326 all
.Children
.Add (IEquatableBoolInfo
= new TypeInfo ("IEquatable<bool>", "IEQUATABLE_BOOL", "OBJECT", true, true, false, true));
1327 all
.Children
.Add (IComparableBoolInfo
= new TypeInfo ("IComparable<bool>", "ICOMPARABLE_BOOL", "OBJECT", true, true, false, true));
1329 all
.Children
.Add (IEquatableDoubleInfo
= new TypeInfo ("IEquatable<double>", "IEQUATABLE_DOUBLE", "OBJECT", true, true, false, true));
1330 all
.Children
.Add (IComparableDoubleInfo
= new TypeInfo ("IComparable<double>", "ICOMPARABLE_DOUBLE", "OBJECT", true, true, false, true));
1332 all
.Children
.Add (IEquatableFloatInfo
= new TypeInfo ("IEquatable<float>", "IEQUATABLE_FLOAT", "OBJECT", true, true, false, true));
1333 all
.Children
.Add (IComparableFloatInfo
= new TypeInfo ("IComparable<float>", "ICOMPARABLE_FLOAT", "OBJECT", true, true, false, true));
1335 all
.Children
.Add (IEquatableCharInfo
= new TypeInfo ("IEquatable<char>", "IEQUATABLE_CHAR", "OBJECT", true, true, false, true));
1336 all
.Children
.Add (IComparableCharInfo
= new TypeInfo ("IComparable<char>", "ICOMPARABLE_CHAR", "OBJECT", true, true, false, true));
1338 all
.Children
.Add (IEquatableIntInfo
= new TypeInfo ("IEquatable<int>", "IEQUATABLE_INT", "OBJECT", true, true, false, true));
1339 all
.Children
.Add (IComparableIntInfo
= new TypeInfo ("IComparable<int>", "ICOMPARABLE_INT", "OBJECT", true, true, false, true));
1341 all
.Children
.Add (IEquatableLongInfo
= new TypeInfo ("IEquatable<long>", "IEQUATABLE_LONG", "OBJECT", true, true, false, true));
1342 all
.Children
.Add (IComparableLongInfo
= new TypeInfo ("IComparable<long>", "ICOMPARABLE_LONG", "OBJECT", true, true, false, true));
1344 all
.Children
.Add (IEquatableStringInfo
= new TypeInfo ("IEquatable<string>", "IEQUATABLE_STRING", "OBJECT", true, true, false, true));
1345 all
.Children
.Add (IComparableStringInfo
= new TypeInfo ("IComparable<string>", "ICOMPARABLE_STRING", "OBJECT", true, true, false, true));
1347 all
.Children
.Add (IEquatableTimeSpanInfo
= new TypeInfo ("IEquatable<TimeSpan>", "IEQUATABLE_TIMESPAN", "OBJECT", true, true, false, true));
1348 all
.Children
.Add (IComparableTimeSpanInfo
= new TypeInfo ("IComparable<TimeSpan>", "ICOMPARABLE_TIMESPAN", "OBJECT", true, true, false, true));
1350 all
.Children
.Add (IEquatableUintInfo
= new TypeInfo ("IEquatable<uint>", "IEQUATABLE_UINT", "OBJECT", true, true, false, true));
1351 all
.Children
.Add (IComparableUintInfo
= new TypeInfo ("IComparable<uint>", "ICOMPARABLE_UINT", "OBJECT", true, true, false, true));
1353 all
.Children
.Add (IEquatableUlongInfo
= new TypeInfo ("IEquatable<ulong>", "IEQUATABLE_ULONG", "OBJECT", true, true, false, true));
1354 all
.Children
.Add (IComparableUlongInfo
= new TypeInfo ("IComparable<ulong>", "ICOMPARABLE_ULONG", "OBJECT", true, true, false, true));
1356 all
.Children
.Add (t
= new TypeInfo ("bool", "BOOL", "OBJECT", true, true, true, false));
1357 t
.Interfaces
.Add (IComparableInfo
);
1358 t
.Interfaces
.Add (IComparableBoolInfo
);
1359 t
.Interfaces
.Add (IConvertibleInfo
);
1360 t
.Interfaces
.Add (IEquatableBoolInfo
);
1362 all
.Children
.Add (t
= new TypeInfo ("float", "FLOAT", "OBJECT", true, true, true, false));
1363 t
.Interfaces
.Add (IComparableInfo
);
1364 t
.Interfaces
.Add (IComparableFloatInfo
);
1365 t
.Interfaces
.Add (IConvertibleInfo
);
1366 t
.Interfaces
.Add (IEquatableFloatInfo
);
1367 t
.Interfaces
.Add (IFormattableInfo
);
1369 all
.Children
.Add (t
= new TypeInfo ("double", "DOUBLE", "OBJECT", true, true, true, false));
1370 t
.Interfaces
.Add (IComparableInfo
);
1371 t
.Interfaces
.Add (IComparableDoubleInfo
);
1372 t
.Interfaces
.Add (IConvertibleInfo
);
1373 t
.Interfaces
.Add (IEquatableDoubleInfo
);
1374 t
.Interfaces
.Add (IFormattableInfo
);
1376 all
.Children
.Add (t
= new TypeInfo ("guint64", "UINT64", "OBJECT", true, true, true, false));
1377 t
.Interfaces
.Add (IComparableInfo
);
1378 t
.Interfaces
.Add (IComparableUlongInfo
);
1379 t
.Interfaces
.Add (IConvertibleInfo
);
1380 t
.Interfaces
.Add (IEquatableUlongInfo
);
1381 t
.Interfaces
.Add (IFormattableInfo
);
1383 all
.Children
.Add (t
= new TypeInfo ("gint64", "INT64", "OBJECT", true, true, true, false));
1384 t
.Interfaces
.Add (IComparableInfo
);
1385 t
.Interfaces
.Add (IComparableLongInfo
);
1386 t
.Interfaces
.Add (IConvertibleInfo
);
1387 t
.Interfaces
.Add (IEquatableLongInfo
);
1388 t
.Interfaces
.Add (IFormattableInfo
);
1390 all
.Children
.Add (t
= new TypeInfo ("guint32", "UINT32", "OBJECT", true, true, true, false));
1391 t
.Interfaces
.Add (IComparableInfo
);
1392 t
.Interfaces
.Add (IComparableUintInfo
);
1393 t
.Interfaces
.Add (IConvertibleInfo
);
1394 t
.Interfaces
.Add (IEquatableUintInfo
);
1395 t
.Interfaces
.Add (IFormattableInfo
);
1397 all
.Children
.Add (t
= new TypeInfo ("gint32", "INT32", "OBJECT", true, true, true, false));
1398 t
.Interfaces
.Add (IComparableInfo
);
1399 t
.Interfaces
.Add (IComparableIntInfo
);
1400 t
.Interfaces
.Add (IConvertibleInfo
);
1401 t
.Interfaces
.Add (IEquatableIntInfo
);
1402 t
.Interfaces
.Add (IFormattableInfo
);
1404 all
.Children
.Add (t
= new TypeInfo ("char*", "STRING", "OBJECT", true, true, true, false));
1405 t
.Interfaces
.Add (IComparableInfo
);
1406 t
.Interfaces
.Add (IComparableStringInfo
);
1407 t
.Interfaces
.Add (IConvertibleInfo
);
1408 t
.Interfaces
.Add (IEquatableStringInfo
);
1409 t
.Interfaces
.Add (IFormattableInfo
);
1411 all
.Children
.Add (t
= new TypeInfo ("TimeSpan", "TIMESPAN", "OBJECT", true, true, true, false));
1412 t
.Interfaces
.Add (IComparableInfo
);
1413 t
.Interfaces
.Add (IComparableTimeSpanInfo
);
1414 t
.Interfaces
.Add (IEquatableTimeSpanInfo
);
1416 all
.Children
.Add (t
= new TypeInfo ("char", "CHAR", "OBJECT", true, true, true, false));
1417 t
.Interfaces
.Add (IComparableInfo
);
1418 t
.Interfaces
.Add (IComparableCharInfo
);
1419 t
.Interfaces
.Add (IConvertibleInfo
);
1420 t
.Interfaces
.Add (IEquatableCharInfo
);
1422 all
.Children
.Add (new TypeInfo ("NPObj", "NPOBJ", "OBJECT", true, true, true, false));
1423 all
.Children
.Add (new TypeInfo ("Managed", "MANAGED", "OBJECT", true, 2, true));
1425 all
.Children
.Add (new TypeInfo ("System.Windows.Input.Cursor", "CURSOR", "OBJECT", true, true));
1426 all
.Children
.Add (new TypeInfo ("System.Windows.Markup.XmlLanguage", "XMLLANGUAGE", "OBJECT", true, true));
1428 // Set IncludeInKinds for all types which inherit from EventObject
1429 foreach (MemberInfo member
in all
.Children
.Values
) {
1430 TypeInfo type
= member
as TypeInfo
;
1433 if (type
.Name
== "EventObject")
1434 type
.Annotations
["IncludeInKinds"] = null;
1436 TypeReference bR
= type
.Base
;
1439 while (bR
!= null) {
1440 if (bR
.Value
== "EventObject") {
1441 member
.Annotations
["IncludeInKinds"] = null;
1444 if (!all
.Children
.TryGetValue (bR
.Value
, out m
))
1458 // Returns false if there are no more tokens (reached end of code)
1459 static bool ParseClassOrStruct (Annotations annotations
, MemberInfo parent
, Tokenizer tokenizer
)
1461 TypeInfo type
= new TypeInfo ();
1463 type
.Annotations
= annotations
;
1464 type
.Header
= tokenizer
.CurrentFile
;
1465 type
.Parent
= parent
;
1467 type
.IsPublic
= tokenizer
.Accept (Token2Type
.Identifier
, "public");
1469 if (tokenizer
.Accept (Token2Type
.Identifier
, "class")) {
1470 type
.IsClass
= true;
1471 } else if (tokenizer
.Accept (Token2Type
.Identifier
, "struct")) {
1472 type
.IsStruct
= true;
1473 type
.IsValueType
= true;
1474 } else if (tokenizer
.Accept (Token2Type
.Identifier
, "union")) {
1475 type
.IsStruct
= true; // Not entirely correct, but a union can be parsed as a struct
1476 type
.IsValueType
= true;
1478 throw new Exception (string.Format ("Expected 'class' or 'struct', not '{0}'", tokenizer
.CurrentToken
.value));
1481 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1482 type
.Name
= tokenizer
.GetIdentifier ();
1484 type
.Name
= "<anonymous>";
1487 if (tokenizer
.Accept (Token2Type
.Punctuation
, ";")) {
1488 // A forward declaration.
1489 //Console.WriteLine ("ParseType: Found a forward declaration to {0}", type.Name);
1493 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1494 if (!tokenizer
.Accept (Token2Type
.Identifier
, "public") && type
.IsClass
)
1495 throw new Exception (string.Format ("The base class of {0} is not public.", type
.Name
));
1497 type
.Base
= ParseTypeReference (tokenizer
);
1499 // accept multiple inheritance the easy way
1500 while (tokenizer
.CurrentToken
.value == ",") {
1501 tokenizer
.Accept (Token2Type
.Punctuation
, ",");
1503 while (tokenizer
.CurrentToken
.value != "," &&
1504 tokenizer
.CurrentToken
.value != "{")
1505 tokenizer
.GetIdentifier ();
1508 //Console.WriteLine ("ParseType: Found {0}'s base class: {1}", type.Name, type.Base);
1511 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "{");
1513 //Console.WriteLine ("ParseType: Found a type: {0} in {1}", type.Name, type.Header);
1514 parent
.Children
.Add (type
);
1515 ParseMembers (type
, tokenizer
);
1517 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "}");
1519 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
)
1520 tokenizer
.Advance (true);
1522 if (tokenizer
.CurrentToken
.value != ";")
1523 throw new Exception (string.Format ("Expected ';', not '{0}'", tokenizer
.CurrentToken
.value));
1525 return tokenizer
.Advance (false);
1528 static bool ParseMembers (MemberInfo parent
, Tokenizer tokenizer
)
1530 Annotations properties
= new Annotations ();
1531 TypeInfo parent_type
= parent
as TypeInfo
;
1532 string accessibility
;
1533 TypeReference returntype
;
1542 //Console.WriteLine ("ParseMembers ({0})", type.Name);
1546 is_dtor
= is_ctor
= is_virtual
= is_static
= false;
1547 is_extern
= is_const
= false;
1549 properties
= new Annotations ();
1551 if (parent_type
!= null)
1552 accessibility
= parent_type
.IsStruct
? "public" : "private";
1554 accessibility
= "public";
1556 if (tokenizer
.Accept (Token2Type
.Punctuation
, ";"))
1559 if (tokenizer
.CurrentToken
.value == "}")
1562 while (tokenizer
.CurrentToken
.type
== Token2Type
.CommentProperty
) {
1563 properties
.Add (tokenizer
.CurrentToken
.value);
1564 tokenizer
.Advance (true);
1567 //Console.WriteLine ("ParseMembers: Current token: {0}", tokenizer.CurrentToken);
1569 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1570 string v
= tokenizer
.CurrentToken
.value;
1576 tokenizer
.Advance (true);
1577 tokenizer
.Accept (Token2Type
.Punctuation
, ":");
1580 ParseEnum (properties
, parent
, tokenizer
);
1583 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ";")) {
1584 tokenizer
.Advance (true);
1590 if (!ParseClassOrStruct (properties
, parent
, tokenizer
))
1594 StringBuilder requisite
= new StringBuilder ();
1595 requisite
.Append (tokenizer
.CurrentToken
.value);
1596 requisite
.Append (' ');
1597 tokenizer
.Advance (true);
1598 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ";")) {
1599 requisite
.Append (tokenizer
.CurrentToken
.value);
1600 requisite
.Append (' ');
1601 if (tokenizer
.CurrentToken
.value == "{") {
1602 tokenizer
.Advance (true);
1603 while (!tokenizer
.Accept (Token2Type
.Punctuation
, "}")) {
1604 requisite
.Append (tokenizer
.CurrentToken
.value);
1605 requisite
.Append (' ');
1606 tokenizer
.Advance (true);
1608 requisite
.Append (tokenizer
.CurrentToken
.value);
1609 requisite
.Append (' ');
1611 tokenizer
.Advance (true);
1613 requisite
.Append (";");
1614 if (properties
.ContainsKey ("CBindingRequisite"))
1615 cbinding_requisites
.AppendLine (requisite
.ToString ());
1618 case "EVENTHANDLER":
1619 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ";"))
1620 tokenizer
.Advance (true);
1623 tokenizer
.Advance (true);
1624 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "<");
1625 tokenizer
.AcceptOrThrow (Token2Type
.Identifier
, "typename");
1626 tokenizer
.GetIdentifier ();
1627 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ">");
1633 if (tokenizer
.Accept (Token2Type
.Identifier
, "virtual")) {
1638 if (tokenizer
.Accept (Token2Type
.Identifier
, "static")) {
1643 if (tokenizer
.Accept (Token2Type
.Identifier
, "const")) {
1648 if (tokenizer
.Accept (Token2Type
.Identifier
, "extern")) {
1653 if (tokenizer
.Accept (Token2Type
.Identifier
, "volatile")) {
1657 if (tokenizer
.Accept (Token2Type
.Identifier
, "G_GNUC_INTERNAL")) {
1664 if (is_extern
&& tokenizer
.Accept (Token2Type
.Literal
, "C")) {
1665 tokenizer
.SyncWithEndBrace ();
1669 if (tokenizer
.Accept (Token2Type
.Punctuation
, "~")) {
1672 TypeInfo ti
= parent
as TypeInfo
;
1673 if (ti
!= null && ti
.Base
!= null)
1674 Console
.WriteLine ("The class {0} has a non-virtual destructor, and it's base class is {2} ({1}).", parent
.Name
, parent
.Header
, ti
!= null && ti
.Base
!= null ? ti
.Base
.Value
: "<none>");
1679 name
= "~" + tokenizer
.GetIdentifier ();
1680 returntype
= new TypeReference ("void");
1682 returntype
= ParseTypeReference (tokenizer
);
1684 if (tokenizer
.CurrentToken
.value == "<") {
1685 tokenizer
.Advance (true);
1686 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ">"))
1687 tokenizer
.Advance (true);
1690 if (returntype
.Value
== parent
.Name
&& tokenizer
.CurrentToken
.value == "(") {
1692 name
= returntype
.Value
;
1693 returntype
.Value
+= "*";
1695 name
= tokenizer
.GetIdentifier ();
1698 returntype
.IsConst
= is_const
;
1699 returntype
.IsReturnType
= true;
1701 //Console.WriteLine ("ParseMembers: found member '{0}' is_ctor: {1}", name, is_ctor);
1703 if (tokenizer
.Accept (Token2Type
.Punctuation
, "(")) {
1705 MethodInfo method
= new MethodInfo ();
1706 method
.Header
= tokenizer
.CurrentFile
;
1707 method
.Parent
= parent
;
1708 method
.Annotations
= properties
;
1710 method
.IsConstructor
= is_ctor
;
1711 method
.IsDestructor
= is_dtor
;
1712 method
.IsVirtual
= is_virtual
;
1713 method
.IsStatic
= is_static
;
1714 method
.IsPublic
= accessibility
== "public";
1715 method
.IsPrivate
= accessibility
== "private";
1716 method
.IsProtected
= accessibility
== "protected";
1717 method
.ReturnType
= returntype
;
1719 //Console.WriteLine ("ParseMembers: found method '{0}' is_ctor: {1}", name, is_ctor);
1721 if (!tokenizer
.Accept (Token2Type
.Punctuation
, ")")) {
1722 string param_value
= null;
1724 ParameterInfo parameter
= new ParameterInfo (method
);
1726 while (tokenizer
.CurrentToken
.type
== Token2Type
.CommentProperty
) {
1727 parameter
.Annotations
.Add (tokenizer
.CurrentToken
.value);
1728 tokenizer
.Advance (true);
1731 if (tokenizer
.Accept (Token2Type
.Punctuation
, ".") && tokenizer
.Accept (Token2Type
.Punctuation
, ".") && tokenizer
.Accept (Token2Type
.Punctuation
, ".")) {
1732 // ... variable argument declaration
1733 parameter
.ParameterType
= new TypeReference ("...");
1735 parameter
.ParameterType
= ParseTypeReference (tokenizer
);
1737 if (tokenizer
.CurrentToken
.value != "," && tokenizer
.CurrentToken
.value != ")") {
1738 parameter
.Name
= tokenizer
.GetIdentifier ();
1739 if (tokenizer
.Accept (Token2Type
.Punctuation
, "[")) {
1740 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
)
1741 tokenizer
.Advance (true);
1742 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "]");
1744 if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1745 param_value
= string.Empty
;
1746 if (tokenizer
.Accept (Token2Type
.Punctuation
, "-"))
1748 param_value
+= tokenizer
.GetIdentifier ();
1749 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1750 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ":");
1751 param_value
+= "::" + tokenizer
.GetIdentifier ();
1755 method
.Parameters
.Add (parameter
);
1756 //Console.WriteLine ("ParseMember: got parameter, type: '{0}' name: '{1}' value: '{2}'", parameter.ParameterType.Value, parameter.Name, param_value);
1757 } while (tokenizer
.Accept (Token2Type
.Punctuation
, ","));
1758 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ")");
1761 parent
.Children
.Add (method
);
1763 //Allow const member functions, ignore the const keyword
1764 tokenizer
.Accept (Token2Type
.Identifier
, "const");
1766 if (tokenizer
.CurrentToken
.value == "{") {
1767 //Console.WriteLine ("ParseMember: member has body, skipping it");
1768 tokenizer
.SyncWithEndBrace ();
1769 } else if (is_ctor
&& tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1770 // ctor method implemented in header with field initializers and/or base class ctor call
1771 tokenizer
.FindStartBrace ();
1772 tokenizer
.SyncWithEndBrace ();
1773 //Console.WriteLine ("ParseMember: skipped ctor method implementation");
1774 } else if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1775 // pure virtual method
1776 tokenizer
.AcceptOrThrow (Token2Type
.Identifier
, "0");
1777 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ";");
1778 method
.IsAbstract
= true;
1780 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ";");
1783 if (is_ctor
|| is_dtor
)
1784 throw new Exception (string.Format ("Expected '(', not '{0}'", tokenizer
.CurrentToken
.value));
1786 if (name
== "operator") {
1788 if (tokenizer
.CurrentToken
.value == ";") {
1791 } else if (tokenizer
.CurrentToken
.value == "{") {
1792 // In-line implementation
1793 tokenizer
.SyncWithEndBrace ();
1796 tokenizer
.Advance (true);
1798 //Console.WriteLine ("ParseMembers: skipped operator");
1800 FieldInfo field
= new FieldInfo ();
1801 field
.IsConst
= is_const
;
1802 field
.IsStatic
= is_static
;
1803 field
.IsExtern
= is_extern
;
1805 field
.FieldType
= returntype
;
1806 field
.IsPublic
= accessibility
== "public";
1807 field
.IsPrivate
= accessibility
== "private";
1808 field
.IsProtected
= accessibility
== "protected";
1809 field
.Annotations
= properties
;
1813 //Console.WriteLine ("ParseMembers: found field '{0}'", name);
1814 field
.Parent
= parent
;
1815 parent
.Children
.Add (field
);
1817 if (tokenizer
.Accept (Token2Type
.Punctuation
, "[")) {
1818 while (!tokenizer
.Accept (Token2Type
.Punctuation
, "]")) {
1819 tokenizer
.Advance (true);
1822 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1823 field
.BitField
= tokenizer
.GetIdentifier ();
1825 if (tokenizer
.Accept (Token2Type
.Punctuation
, ",")) {
1826 field
= new FieldInfo ();
1827 if (tokenizer
.Accept (Token2Type
.Punctuation
, "*")) {
1830 field
.Name
= tokenizer
.GetIdentifier ();
1831 field
.FieldType
= returntype
;
1834 if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1835 tokenizer
.Advance (true); /* this can be an arbitrary long expression, sync with the ';'? */
1840 tokenizer
.Accept (Token2Type
.Punctuation
, ";");
1846 static void ParseEnum (Annotations properties
, MemberInfo parent
, Tokenizer tokenizer
)
1849 StringBuilder
value = new StringBuilder ();
1850 TypeInfo type
= new TypeInfo ();
1852 type
.Annotations
= properties
;
1855 tokenizer
.AcceptOrThrow (Token2Type
.Identifier
, "enum");
1856 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1857 type
.Name
= tokenizer
.GetIdentifier ();
1859 type
.Name
= "<anonymous>";
1861 parent
.Children
.Add (type
);
1863 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "{");
1865 //Console.WriteLine ("ParseEnum: {0}", name);
1867 while (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1868 field
= new FieldInfo ();
1869 field
.Name
= tokenizer
.GetIdentifier ();
1871 if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1872 while (tokenizer
.CurrentToken
.value != "," && tokenizer
.CurrentToken
.value != "}") {
1874 value.Append (tokenizer
.CurrentToken
.value);
1875 tokenizer
.Advance (true);
1878 field
.Value
= value.ToString ();
1879 type
.Children
.Add (field
);
1880 //Console.WriteLine ("ParseEnum: {0}: {1} {2} {3}", name, field, value.Length != 0 != null ? "=" : "", value);
1882 if (!tokenizer
.Accept (Token2Type
.Punctuation
, ","))
1886 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "}");
1887 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ";");
1890 public static TypeReference
ParseTypeReference (Tokenizer tokenizer
)
1892 TypeReference tr
= new TypeReference ();
1893 StringBuilder result
= new StringBuilder ();
1895 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1898 if (tokenizer
.Accept (Token2Type
.Identifier
, "unsigned"))
1899 result
.Append ("unsigned");
1901 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1904 result
.Append (tokenizer
.GetIdentifier ());
1906 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1907 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ":");
1908 result
.Append ("::");
1909 result
.Append (tokenizer
.GetIdentifier ());
1912 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1915 while (tokenizer
.Accept (Token2Type
.Punctuation
, "*"))
1916 result
.Append ("*");
1918 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1921 if (tokenizer
.Accept (Token2Type
.Punctuation
, "&"))
1922 result
.Append ("&");
1924 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1927 //Console.WriteLine ("ParseTypeReference: parsed '{0}'", result.ToString ());
1929 tr
.Value
= result
.ToString ();
1934 public static string getU (string v
)
1936 if (v
.Contains ("::"))
1937 v
= v
.Substring (v
.IndexOf ("::") + 2);
1940 v
= v
.Replace ("DEPENDENCYOBJECT", "DEPENDENCY_OBJECT");
1941 if (v
.Length
> "COLLECTION".Length
&& !v
.StartsWith ("COLLECTION"))
1942 v
= v
.Replace ("COLLECTION", "_COLLECTION");
1943 if (v
.Length
> "DICTIONARY".Length
)
1944 v
= v
.Replace ("DICTIONARY", "_DICTIONARY");
1948 public void GenerateTypes_G (GlobalInfo all
)
1950 string base_dir
= Environment
.CurrentDirectory
;
1951 string class_dir
= Path
.Combine (base_dir
, "class");
1952 string moon_moonlight_dir
= Path
.Combine (class_dir
, "System.Windows");
1953 List
<TypeInfo
> types
= new List
<TypeInfo
> (all
.GetDependencyObjects ());
1955 StringBuilder text
= new StringBuilder ();
1957 Helper
.WriteWarningGenerated (text
);
1959 text
.AppendLine ("using Mono;");
1960 text
.AppendLine ("using System;");
1961 text
.AppendLine ("using System.Reflection;");
1962 text
.AppendLine ("using System.Collections.Generic;");
1963 text
.AppendLine ("");
1964 text
.AppendLine ("namespace Mono {");
1965 text
.AppendLine ("\tpartial class Types {");
1966 text
.AppendLine ("\t\tprivate void CreateNativeTypes ()");
1967 text
.AppendLine ("\t\t{");
1968 text
.AppendLine ("\t\t\tType t;");
1969 text
.AppendLine ("\t\t\ttry {");
1971 foreach (MemberInfo m
in all
.Children
.Values
) {
1972 TypeInfo t
= m
as TypeInfo
;
1975 if (types
.Contains (t
))
1980 types
.Sort (new Members
.MembersSortedByManagedFullName
<TypeInfo
> ());
1982 for (int i
= 0; i
< types
.Count
; i
++) {
1983 TypeInfo t
= types
[i
];
1984 string type
= t
.ManagedName
;
1986 if (String
.IsNullOrEmpty (t
.Namespace
) || t
.Namespace
== "None" || t
.Name
.StartsWith ("MoonWindow"))
1989 if (type
== "PresentationFrameworkCollection`1")
1990 type
= "PresentationFrameworkCollection<>";
1992 //Log.WriteLine ("Found Kind.{0} in {1} which result in type: {2}.{3}", kind, file, ns, type);
1994 text
.Append ("\t\t\t\tt = typeof (");
1995 text
.Append (t
.Namespace
);
1998 text
.AppendLine ("); ");
2000 text
.Append ("\t\t\t\ttypes.Add (t, new ManagedType (t, Kind.");
2001 text
.Append (t
.KindName
);
2002 text
.AppendLine ("));");
2005 // now handle the primitive types
2006 output_native_type_delegate f
= delegate (string t
, string k
) {
2007 text
.Append ("\t\t\t\tt = typeof (");
2009 text
.AppendLine (");");
2012 text
.Append ("\t\t\t\ttypes.Add (t, new ManagedType (t, Kind.");
2014 text
.AppendLine ("));");
2017 f ("char", "UINT32");
2018 f ("object", "OBJECT");
2020 f ("double", "DOUBLE");
2021 f ("float", "FLOAT");
2022 f ("ulong", "UINT64");
2023 f ("long", "INT64");
2024 f ("uint", "UINT32");
2026 f ("string", "STRING");
2027 f ("TimeSpan", "TIMESPAN");
2029 // all the interfaces
2030 f ("IComparable", "ICOMPARABLE");
2031 f ("IFormattable", "IFORMATTABLE");
2032 f ("IConvertible", "ICONVERTIBLE");
2033 f ("IEquatable<bool>", "IEQUATABLE_BOOL");
2034 f ("IComparable<bool>", "ICOMPARABLE_BOOL");
2035 f ("IEquatable<double>", "IEQUATABLE_DOUBLE");
2036 f ("IComparable<double>", "ICOMPARABLE_DOUBLE");
2037 f ("IEquatable<float>", "IEQUATABLE_FLOAT");
2038 f ("IComparable<float>", "ICOMPARABLE_FLOAT");
2039 f ("IEquatable<char>", "IEQUATABLE_CHAR");
2040 f ("IComparable<char>", "ICOMPARABLE_CHAR");
2041 f ("IEquatable<int>", "IEQUATABLE_INT");
2042 f ("IComparable<int>", "ICOMPARABLE_INT");
2043 f ("IEquatable<long>", "IEQUATABLE_LONG");
2044 f ("IComparable<long>", "ICOMPARABLE_LONG");
2045 f ("IEquatable<string>", "IEQUATABLE_STRING");
2046 f ("IComparable<string>", "ICOMPARABLE_STRING");
2047 f ("IEquatable<TimeSpan>", "IEQUATABLE_TIMESPAN");
2048 f ("IComparable<TimeSpan>", "ICOMPARABLE_TIMESPAN");
2049 f ("IEquatable<uint>", "IEQUATABLE_UINT");
2050 f ("IComparable<uint>", "ICOMPARABLE_UINT");
2051 f ("IEquatable<ulong>", "IEQUATABLE_ULONG");
2052 f ("IComparable<ulong>", "ICOMPARABLE_ULONG");
2054 f ("System.Windows.Application", "APPLICATION");
2055 f ("System.Windows.Thickness", "THICKNESS");
2056 f ("System.Windows.CornerRadius", "CORNERRADIUS");
2057 f ("System.Windows.PropertyPath", "PROPERTYPATH");
2058 f ("System.Windows.Point", "POINT");
2059 f ("System.Windows.Rect", "RECT");
2060 f ("System.Windows.Size", "SIZE");
2061 f ("System.Windows.FontStretch", "FONTSTRETCH");
2062 f ("System.Windows.FontWeight", "FONTWEIGHT");
2063 f ("System.Windows.FontStyle", "FONTSTYLE");
2064 f ("System.Windows.Input.Cursor", "CURSOR");
2065 f ("System.Windows.Media.FontFamily", "FONTFAMILY");
2066 f ("System.Windows.Markup.XmlLanguage", "XMLLANGUAGE");
2068 text
.AppendLine ("\t\t\t} catch (Exception ex) {");
2069 text
.AppendLine ("\t\t\t\tConsole.WriteLine (\"There was an error while loading native types: \" + ex.ToString ());");
2070 text
.AppendLine ("\t\t\t}");
2071 text
.AppendLine ("\t\t}");
2072 text
.AppendLine ("\t}");
2073 text
.AppendLine ("}");
2075 Log
.WriteLine ("typeandkidngen done");
2077 Helper
.WriteAllText (Path
.Combine (Path
.Combine (moon_moonlight_dir
, "Mono"), "Types.g.cs"), text
.ToString ());
2080 private static void GenerateCBindings (GlobalInfo info
, string dir
)
2082 List
<MethodInfo
> methods
;
2083 StringBuilder header
= new StringBuilder ();
2084 StringBuilder impl
= new StringBuilder ();
2085 List
<string> headers
= new List
<string> ();
2086 List
<string> classes
= new List
<string> ();
2087 List
<string> structs
= new List
<string> ();
2089 string last_type
= string.Empty
;
2091 methods
= info
.CPPMethodsToBind
;
2093 Helper
.WriteWarningGenerated (header
);;
2094 Helper
.WriteWarningGenerated (impl
);
2096 header
.AppendLine ("#ifndef __MOONLIGHT_C_BINDING_H__");
2097 header
.AppendLine ("#define __MOONLIGHT_C_BINDING_H__");
2098 header
.AppendLine ();
2099 header
.AppendLine ("#include <glib.h>");
2100 header
.AppendLine ("#include <cairo.h>");
2101 header
.AppendLine ();
2102 header
.AppendLine ("#include \"enums.h\"");
2103 header
.AppendLine ();
2104 foreach (MemberInfo member
in info
.Children
.Values
) {
2105 TypeInfo type
= member
as TypeInfo
;
2110 if (!classes
.Contains (type
.Name
))
2111 classes
.Add (type
.Name
);
2112 } else if (type
.IsStruct
) {
2113 if (!structs
.Contains (type
.Name
))
2114 structs
.Add (type
.Name
);
2118 foreach (MemberInfo method
in methods
) {
2121 if (method
.ParentType
!= null) {
2122 TypeInfo type
= method
.ParentType
;
2124 if (!classes
.Contains (type
.Name
))
2125 classes
.Add (type
.Name
);
2126 } else if (type
.IsStruct
) {
2127 if (!structs
.Contains (type
.Name
))
2128 structs
.Add (type
.Name
);
2132 if (string.IsNullOrEmpty (method
.Header
))
2134 if (!method
.Header
.StartsWith (dir
))
2137 h
= Path
.GetFileName (method
.Header
);
2139 if (!headers
.Contains (h
))
2142 header
.AppendLine (forward_decls
.ToString ());
2145 foreach (string c
in classes
) {
2146 header
.Append ("class ");
2148 header
.AppendLine (";");
2150 header
.AppendLine ();
2151 foreach (string s
in structs
) {
2152 header
.Append ("struct ");
2154 header
.AppendLine (";");
2156 header
.AppendLine ();
2157 header
.AppendLine (cbinding_requisites
.ToString ());
2159 header
.AppendLine ();
2160 header
.AppendLine ("G_BEGIN_DECLS");
2161 header
.AppendLine ();
2163 impl
.AppendLine ("#include <config.h>");
2165 impl
.AppendLine ("#include <stdio.h>");
2166 impl
.AppendLine ("#include <stdlib.h>");
2168 impl
.AppendLine ("#include \"cbinding.h\"");
2171 foreach (string h
in headers
) {
2172 impl
.Append ("#include \"");
2174 impl
.AppendLine ("\"");
2177 foreach (MemberInfo member
in methods
) {
2178 MethodInfo method
= (MethodInfo
) member
;
2180 if (!method
.Header
.StartsWith (dir
))
2183 if (last_type
!= method
.Parent
.Name
) {
2184 last_type
= method
.Parent
.Name
;
2185 foreach (StringBuilder text
in new StringBuilder
[] {header, impl}
) {
2186 text
.AppendLine ("/**");
2187 text
.Append (" * ");
2188 text
.AppendLine (last_type
);
2189 text
.AppendLine (" **/");
2193 WriteHeaderMethod (method
.CMethod
, method
, header
, info
);
2194 header
.AppendLine ();
2196 WriteImplMethod (method
.CMethod
, method
, impl
, info
);
2201 header
.AppendLine ();
2202 header
.AppendLine ("G_END_DECLS");
2203 header
.AppendLine ();
2204 header
.AppendLine ("#endif");
2206 Helper
.WriteAllText (Path
.Combine (dir
, "cbinding.h"), header
.ToString ());
2207 Helper
.WriteAllText (Path
.Combine (dir
, "cbinding.cpp"), impl
.ToString ());
2210 public static void GenerateCBindings (GlobalInfo info
)
2212 string base_dir
= Environment
.CurrentDirectory
;
2213 string plugin_dir
= Path
.Combine (base_dir
, "plugin");
2214 string moon_dir
= Path
.Combine (base_dir
, "src");
2216 GenerateCBindings (info
, moon_dir
);
2217 GenerateCBindings (info
, plugin_dir
);
2220 static void WriteHeaderMethod (MethodInfo cmethod
, MethodInfo cppmethod
, StringBuilder text
, GlobalInfo info
)
2222 Log
.WriteLine ("Writing header: {0}::{1} (Version: '{2}', GenerateManaged: {3})",
2223 cmethod
.Parent
.Name
, cmethod
.Name
,
2224 cmethod
.Annotations
.GetValue ("Version"),
2225 cmethod
.Annotations
.ContainsKey ("GenerateManaged"));
2227 if (cmethod
.Annotations
.ContainsKey ("GeneratePInvoke"))
2228 text
.AppendLine ("/* @GeneratePInvoke */");
2229 cmethod
.ReturnType
.Write (text
, SignatureType
.NativeC
, info
);
2230 if (!cmethod
.ReturnType
.IsPointer
)
2232 text
.Append (cmethod
.Name
);
2233 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, false);
2234 text
.AppendLine (";");
2237 static void WriteImplMethod (MethodInfo cmethod
, MethodInfo cppmethod
, StringBuilder text
, GlobalInfo info
)
2239 bool is_void
= cmethod
.ReturnType
.Value
== "void";
2240 bool is_ctor
= cmethod
.IsConstructor
;
2241 bool is_static
= cmethod
.IsStatic
;
2242 bool is_dtor
= cmethod
.IsDestructor
;
2243 bool check_instance
= !is_static
&& !is_ctor
;
2244 bool check_error
= false;
2246 foreach (ParameterInfo parameter
in cmethod
.Parameters
) {
2247 if (parameter
.ParameterType
.Value
== "MoonError*") {
2253 cmethod
.ReturnType
.Write (text
, SignatureType
.NativeC
, info
);
2255 text
.Append (cmethod
.Name
);
2256 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, false);
2257 text
.AppendLine ("");
2258 text
.AppendLine ("{");
2261 text
.Append ("\treturn new ");
2262 text
.Append (cmethod
.Parent
.Name
);
2263 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, true);
2264 text
.AppendLine (";");
2265 } else if (is_dtor
) {
2266 text
.AppendLine ("\tdelete instance;");
2268 if (check_instance
) {
2269 text
.AppendLine ("\tif (instance == NULL)");
2271 if (cmethod
.ReturnType
.Value
== "void") {
2272 text
.Append ("\t\treturn");
2273 } else if (cmethod
.ReturnType
.Value
.Contains ("*")) {
2274 text
.Append ("\t\treturn NULL");
2275 } else if (cmethod
.ReturnType
.Value
== "Type::Kind") {
2276 text
.Append ("\t\treturn Type::INVALID");
2277 } else if (cmethod
.ReturnType
.Value
== "bool") {
2278 text
.Append ("\t\treturn false");
2279 } else if (cmethod
.ReturnType
.Value
== "Point") {
2280 text
.Append ("\t\treturn Point (0, 0)");
2282 text
.AppendLine ("\t\t// Need to find a proper way to get the default value for the specified type and return that if instance is NULL.");
2283 text
.Append ("\t\treturn");
2285 text
.Append (cmethod
.ReturnType
.Value
);
2286 text
.Append (") 0");
2288 text
.AppendLine (";");
2290 text
.AppendLine ("\t");
2294 text
.AppendLine ("\tif (error == NULL)");
2295 text
.Append ("\t\tg_warning (\"Moonlight: Called ");
2296 text
.Append (cmethod
.Name
);
2297 text
.AppendLine (" () with error == NULL.\");");
2302 text
.Append ("return ");
2305 text
.Append (cmethod
.Parent
.Name
);
2308 text
.Append ("instance->");
2309 cmethod
.Parameters
[0].DisableWriteOnce
= true;
2311 text
.Append (cppmethod
.Name
);
2312 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, true);
2313 text
.AppendLine (";");
2316 text
.AppendLine ("}");
2319 static void GenerateTypeStaticCpp (GlobalInfo all
)
2322 List
<string> headers
= new List
<string> ();
2324 StringBuilder text
= new StringBuilder ();
2326 Helper
.WriteWarningGenerated (text
);
2328 text
.AppendLine ("#include <config.h>");
2330 text
.AppendLine ("#include <stdlib.h>");
2332 headers
.Add ("cbinding.h");
2333 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
2334 if (t
.C_Constructor
== string.Empty
|| t
.C_Constructor
== null || !t
.GenerateCBindingCtor
) {
2335 //Console.WriteLine ("{0} does not have a C ctor", t.FullName);
2336 if (t
.GetTotalEventCount () == 0)
2340 if (string.IsNullOrEmpty (t
.Header
)) {
2341 // Console.WriteLine ("{0} does not have a header", t.FullName);
2345 //Console.WriteLine ("{0}'s header is {1}", t.FullName, t.Header);
2347 header
= Path
.GetFileName (t
.Header
);
2348 if (!headers
.Contains (header
))
2349 headers
.Add (header
);
2352 // Loop through all the classes and check which headers
2353 // are needed for the c constructors
2354 text
.AppendLine ("");
2356 foreach (string h
in headers
) {
2357 text
.Append ("#include \"");
2359 text
.AppendLine ("\"");
2363 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
2364 if (t
.GetEventCount () == 0)
2368 foreach (FieldInfo field
in t
.Events
) {
2369 text
.Append ("const int ");
2370 text
.Append (t
.Name
);
2372 text
.Append (field
.EventName
);
2373 text
.Append ("Event = ");
2374 text
.Append (t
.GetEventId (field
));
2375 text
.AppendLine (";");
2379 // Create the arrays of event names for the classes which have events
2380 text
.AppendLine ("");
2381 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
2383 if (t
.Events
.Count
> 0) {
2384 text
.Append ("const char *");
2385 text
.Append (t
.KindName
);
2386 text
.Append ("_Events [] = { ");
2388 foreach (FieldInfo field
in t
.Events
) {
2390 text
.Append (field
.EventName
);
2391 text
.Append ("\", ");
2394 text
.AppendLine ("NULL };");
2397 if (t
.Interfaces
.Count
> 0) {
2398 text
.Append ("const Type::Kind ");
2399 text
.Append (t
.KindName
);
2400 text
.Append ("_Interfaces[] = { ");
2402 for (int i
= 0; i
< t
.Interfaces
.Count
; i
++) {
2403 text
.Append ("Type::");
2404 text
.Append (t
.Interfaces
[i
].KindName
);
2405 if (i
< t
.Interfaces
.Count
- 1)
2409 text
.AppendLine (" };");
2413 // Create the array of type data
2414 text
.AppendLine ("");
2415 text
.AppendLine ("void");
2416 text
.AppendLine ("Types::RegisterNativeTypes ()");
2417 text
.AppendLine ("{");
2418 text
.AppendLine ("\tDeployment *deployment = Deployment::GetCurrent ();");
2419 text
.AppendLine ("\ttypes [(int) Type::INVALID] = new Type (deployment, Type::INVALID, Type::INVALID, false, false, NULL, 0, 0, NULL, 0, NULL, false, NULL, NULL );");
2420 foreach (TypeInfo type
in all
.Children
.SortedTypesByKind
) {
2422 TypeInfo parent
= null;
2423 string events
= "NULL";
2424 string interfaces
= "NULL";
2426 if (!type
.Annotations
.ContainsKey ("IncludeInKinds"))
2429 if (type
.Base
!= null && type
.Base
.Value
!= null && all
.Children
.TryGetValue (type
.Base
.Value
, out member
))
2430 parent
= (TypeInfo
) member
;
2432 if (type
.Events
!= null && type
.Events
.Count
!= 0)
2433 events
= type
.KindName
+ "_Events";
2435 if (type
.Interfaces
.Count
!= 0)
2436 interfaces
= type
.KindName
+ "_Interfaces";
2438 text
.AppendLine (string.Format (@" types [(int) {0}] = new Type (deployment, {0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12});",
2439 "Type::" + type
.KindName
,
2440 type
.KindName
== "OBJECT" ? "Type::INVALID" : ("Type::" + (parent
!= null ? parent
.KindName
: "OBJECT")),
2441 type
.IsValueType
? "true" : "false",
2442 type
.IsInterface
? "true" : "false",
2443 "\"" + type
.Name
+ "\"",
2444 type
.GetEventCount (),
2445 type
.GetTotalEventCount (),
2447 type
.Interfaces
.Count
,
2449 type
.DefaultCtorVisible
? "true" : "false",
2450 (type
.C_Constructor
!= null && type
.GenerateCBindingCtor
) ? string.Concat ("(create_inst_func *) ", type
.C_Constructor
) : "NULL",
2451 type
.ContentProperty
!= null ? string.Concat ("\"", type
.ContentProperty
, "\"") : "NULL"
2456 text
.AppendLine ("\ttypes [(int) Type::LASTTYPE] = new Type (deployment, Type::LASTTYPE, Type::INVALID, false, false, NULL, 0, 0, NULL, 0, NULL, false, NULL, NULL);");
2458 text
.AppendLine ("}");
2462 Helper
.WriteAllText ("src/type-generated.cpp", text
.ToString ());
2465 static void GenerateTypeH (GlobalInfo all
)
2467 const string file
= "src/type.h";
2469 string contents
= File
.ReadAllText (file
+ ".in");
2471 contents
= contents
.Replace ("/*DO_KINDS*/", all
.Children
.GetKindsForEnum ().ToString ());
2473 text
= new StringBuilder ();
2475 Helper
.WriteWarningGenerated (text
);
2477 contents
= text
.ToString () + contents
;
2479 Helper
.WriteAllText (file
, contents
);
2482 static void GenerateKindCs ()
2484 const string file
= "src/type.h";
2485 StringBuilder text
= new StringBuilder ();
2486 string contents
= File
.ReadAllText (file
);
2487 int a
= contents
.IndexOf ("// START_MANAGED_MAPPING") + "// START_MANAGED_MAPPING".Length
;
2488 int b
= contents
.IndexOf ("// END_MANAGED_MAPPING");
2489 string values
= contents
.Substring (a
, b
- a
);
2491 Helper
.WriteWarningGenerated (text
);
2493 text
.AppendLine ("namespace Mono {");
2494 text
.AppendLine ("#if NET_2_1");
2495 text
.AppendLine ("\tinternal enum Kind {");
2496 text
.AppendLine ("#else");
2497 text
.AppendLine ("\tpublic enum Kind {");
2498 text
.AppendLine ("#endif");
2499 text
.AppendLine (values
);
2500 text
.AppendLine ("\t}");
2501 text
.AppendLine ("}");
2503 string realfile
= "class/System.Windows/Mono/Kind.cs".Replace ('/', Path
.DirectorySeparatorChar
);
2504 Helper
.WriteAllText (realfile
, text
.ToString ());
2507 static void GenerateValueH (GlobalInfo all
)
2509 const string file
= "src/value.h";
2510 StringBuilder result
= new StringBuilder ();
2512 Helper
.WriteWarningGenerated (result
);
2514 using (StreamReader reader
= new StreamReader (file
+ ".in")) {
2516 line
= reader
.ReadLine ();
2517 while (line
!= null) {
2518 if (line
.Contains ("/*DO_FWD_DECLS*/")) {
2519 foreach (TypeInfo type
in all
.Children
.SortedTypesByKind
) {
2520 if (!type
.Annotations
.ContainsKey("IncludeInKinds") ||
2521 type
.Annotations
.ContainsKey("SkipValue") ||
2526 if (type
.IsStruct
) {
2527 forward_decls
.Append ("struct ");
2529 forward_decls
.Append ("class ");
2531 forward_decls
.Append (type
.Name
);
2532 forward_decls
.AppendLine (";");
2534 forward_decls
.AppendLine ();
2535 result
.Append (forward_decls
.ToString ());
2536 } else if (line
.Contains ("/*DO_AS*/")) {
2537 foreach (TypeInfo type
in all
.Children
.SortedTypesByKind
) {
2538 if (!type
.Annotations
.ContainsKey("IncludeInKinds") ||
2539 type
.Annotations
.ContainsKey("SkipValue") ||
2544 //do_as.AppendLine (string.Format (" {1,-30} As{0} () {{ checked_get_subclass (Type::{2}, {0}) }}", type.Name, type.Name + "*", type.KindName));
2546 result
.Append ('\t');
2547 result
.Append (type
.Name
);
2548 result
.Append ("*");
2549 result
.Append (' ', 40 - type
.Name
.Length
);
2550 result
.Append ("As");
2551 result
.Append (type
.Name
);
2552 result
.Append (" (Types *types = NULL) { checked_get_subclass (Type::");
2553 result
.Append (type
.KindName
);
2554 result
.Append (", ");
2555 result
.Append (type
.Name
);
2556 result
.Append (") }");
2557 result
.AppendLine ();
2559 result
.AppendLine ();
2561 result
.AppendLine (line
);
2563 line
= reader
.ReadLine ();
2567 Helper
.WriteAllText (file
, result
.ToString ());
2571 static bool IsManuallyDefined (string NativeMethods_cs
, string method
)
2573 if (NativeMethods_cs
.Contains (" " + method
+ " "))
2575 else if (NativeMethods_cs
.Contains (" " + method
+ "("))
2577 else if (NativeMethods_cs
.Contains ("\"" + method
+ "\""))
2584 static void GeneratePInvokes (GlobalInfo all
)
2586 string base_dir
= Environment
.CurrentDirectory
;
2587 List
<MethodInfo
> methods
= new List
<MethodInfo
> ();
2588 StringBuilder text
= new StringBuilder ();
2589 string NativeMethods_cs
;
2591 NativeMethods_cs
= File
.ReadAllText (Path
.Combine (base_dir
, "class/System.Windows/Mono/NativeMethods.cs".Replace ('/', Path
.DirectorySeparatorChar
)));
2593 methods
= all
.CPPMethodsToBind
;
2595 foreach (MemberInfo info
in all
.Children
.Values
) {
2596 MethodInfo minfo
= info
as MethodInfo
;
2599 if (!minfo
.Annotations
.ContainsKey ("GeneratePInvoke"))
2601 foreach (MethodInfo mi
in methods
) {
2602 if (mi
.CMethod
.Name
== minfo
.Name
) {
2609 //Console.WriteLine ("Added: {0} IsSrc: {1} IsPlugin: {2} Header: {3}", minfo.Name, minfo.IsSrcMember, minfo.IsPluginMember, minfo.Header);
2610 methods
.Add (minfo
);
2613 Helper
.WriteWarningGenerated (text
);
2614 text
.AppendLine ("using System;");
2615 text
.AppendLine ("using System.Windows;");
2616 text
.AppendLine ("using System.Runtime.InteropServices;");
2617 text
.AppendLine ("");
2618 text
.AppendLine ("namespace Mono {");
2619 text
.AppendLine ("\tinternal static partial class NativeMethods");
2620 text
.AppendLine ("\t{");
2621 text
.AppendLine ("\t\t/* moonplugin methods */");
2622 text
.AppendLine ("\t");
2623 foreach (MethodInfo method
in methods
) {
2624 if (!method
.IsPluginMember
|| !method
.Annotations
.ContainsKey ("GeneratePInvoke"))
2626 WritePInvokeMethod (NativeMethods_cs
, method
, text
, "moonplugin");
2630 text
.AppendLine ("\t");
2631 text
.AppendLine ("\t\t/* libmoon methods */");
2632 text
.AppendLine ("\t");
2633 foreach (MethodInfo method
in methods
) {
2634 if (!method
.IsSrcMember
|| !method
.Annotations
.ContainsKey ("GeneratePInvoke"))
2636 WritePInvokeMethod (NativeMethods_cs
, method
, text
, "moon");
2639 text
.AppendLine ("\t}");
2640 text
.AppendLine ("}");
2642 Helper
.WriteAllText (Path
.Combine (base_dir
, "class/System.Windows/Mono/GeneratedPInvokes.cs".Replace ('/', Path
.DirectorySeparatorChar
)), text
.ToString ());
2645 static void WritePInvokeMethod (string NativeMethods_cs
, MethodInfo method
, StringBuilder text
, string library
)
2647 bool marshal_string_returntype
= false;
2648 bool marshal_moonerror
= false;
2649 bool generate_wrapper
= false;
2650 // bool is_manually_defined;
2652 bool is_void
= false;
2653 bool contains_unknown_types
;
2655 string managed_name
;
2657 TypeReference returntype
;
2658 MethodInfo cmethod
= method
.CMethod
;
2659 ParameterInfo error_parameter
= null;
2661 if (method
.ReturnType
== null)
2662 throw new Exception (string.Format ("Method {0} in type {1} does not have a return type.", method
.Name
, method
.Parent
.Name
));
2664 if (method
.ReturnType
.Value
== "char*") {
2665 marshal_string_returntype
= true;
2666 generate_wrapper
= true;
2667 } else if (method
.ReturnType
.Value
== "void") {
2671 // Check for parameters we can automatically generate code for.
2672 foreach (ParameterInfo parameter
in cmethod
.Parameters
) {
2673 if (parameter
.Name
== "error" && parameter
.ParameterType
.Value
== "MoonError*") {
2674 marshal_moonerror
= true;
2675 generate_wrapper
= true;
2676 error_parameter
= parameter
;
2680 name
= method
.CMethod
.Name
;
2681 managed_name
= name
;
2682 if (marshal_moonerror
)
2683 managed_name
= managed_name
.Replace ("_with_error", "");
2685 returntype
= method
.ReturnType
;
2686 // is_manually_defined = IsManuallyDefined (NativeMethods_cs, managed_name);
2687 contains_unknown_types
= method
.ContainsUnknownTypes
;
2688 comment_out
= contains_unknown_types
;
2689 tabs
= comment_out
? "\t\t// " : "\t\t";
2691 // if (is_manually_defined)
2692 // text.AppendLine ("\t\t// NOTE: There is a method in NativeMethod.cs with the same name.");
2694 if (contains_unknown_types
)
2695 text
.AppendLine ("\t\t// This method contains types the generator didn't know about. Fix the generator (find the method 'GetManagedType' in TypeReference.cs and add the missing case) and try again.");
2698 text
.Append ("[DllImport (\"");
2699 text
.Append (library
);
2700 if (generate_wrapper
) {
2701 text
.Append ("\", EntryPoint=\"");
2704 text
.AppendLine ("\")]");
2706 if (method
.ReturnType
.Value
== "bool") {
2708 text
.AppendLine ("[return: MarshalAs (UnmanagedType.U1)]");
2709 } else if (method
.ReturnType
.Value
== "gboolean") {
2711 text
.AppendLine ("[return: MarshalAs (UnmanagedType.Bool)]");
2714 // Always output the native signature too, makes it easier to check if the generation is wrong.
2715 text
.Append ("\t\t// ");
2716 cmethod
.WriteFormatted (text
);
2720 text
.Append (generate_wrapper
? "private " : "public ");
2721 text
.Append ("extern static ");
2722 if (marshal_string_returntype
)
2723 text
.Append ("IntPtr");
2725 returntype
.Write (text
, SignatureType
.PInvoke
, null);
2728 if (generate_wrapper
)
2730 cmethod
.Parameters
.Write (text
, SignatureType
.PInvoke
, false);
2731 text
.AppendLine (";");
2733 if (generate_wrapper
) {
2735 text
.Append ("public static ");
2736 returntype
.Write (text
, SignatureType
.Managed
, null);
2738 text
.Append (managed_name
);
2740 foreach (ParameterInfo parameter
in cmethod
.Parameters
)
2741 parameter
.DisableWriteOnce
= parameter
.ManagedWrapperCode
!= null;
2743 if (error_parameter
!= null)
2744 error_parameter
.DisableWriteOnce
= true;
2746 cmethod
.Parameters
.Write (text
, SignatureType
.Managed
, false);
2755 if (marshal_string_returntype
) {
2756 text
.AppendLine ("\tIntPtr result;");
2757 } else if (!is_void
) {
2759 returntype
.Write (text
, SignatureType
.Managed
, null);
2760 text
.AppendLine (" result;");
2763 if (marshal_moonerror
) {
2765 text
.AppendLine ("\tMoonError error;");
2771 text
.Append ("result = ");
2773 text
.Append (cmethod
.Name
);
2775 cmethod
.Parameters
.Write (text
, SignatureType
.Managed
, true);
2777 text
.AppendLine (";");
2779 if (marshal_moonerror
) {
2781 text
.AppendLine ("\tif (error.Number != 0)");
2784 text
.AppendLine ("\t\tthrow CreateManagedException (error);");
2787 if (marshal_string_returntype
) {
2789 text
.AppendLine ("\tif (result == IntPtr.Zero)");
2791 text
.AppendLine ("\t\treturn null;");
2793 text
.AppendLine ("\tstring s = Marshal.PtrToStringAnsi (result);\t// *copy* unmanaged string");
2795 if (!method
.ReturnType
.IsConst
) {
2796 text
.AppendLine ("\tMarshal.FreeHGlobal (result);\t\t\t// g_free the unmanaged string");
2799 text
.AppendLine ("\treturn s;");
2800 } else if (!is_void
) {
2802 text
.AppendLine ("\treturn result;");
2812 static void RemoveExcludedSrcFiles (string srcdir
, List
<string> files
)
2814 files
.Remove (Path
.Combine (srcdir
, "cbinding.h"));
2815 files
.Remove (Path
.Combine (srcdir
, "ptr.h"));