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 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 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.Media.Animation;");
522 text
.AppendLine ("using System.Windows.Shapes;");
525 for (int i
= 0; i
< types
.Count
; i
++) {
526 TypeInfo type
= types
[i
];
527 bool call_initialize
= type
.Annotations
.ContainsKey ("CallInitialize");
532 if (string.IsNullOrEmpty (ns
)) {
533 Console
.WriteLine ("The type '{0}' in {1} does not have a namespace annotation.", type
.FullName
, Path
.GetFileName (type
.Header
));
538 //Console.WriteLine ("The type '{0}''s Namespace annotation is 'None'.", type.FullName);
542 string check_ns
= Path
.Combine (Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), ns
), type
.ManagedName
.Replace ("`1", "") + ".cs");
543 if (!File
.Exists (check_ns
)) {
544 Console
.WriteLine ("The file {0} does not exist, did you annotate the class with the wrong namespace?", check_ns
);
548 if (previous_namespace
!= ns
) {
549 if (previous_namespace
!= string.Empty
) {
550 text
.AppendLine ("}");
553 text
.Append ("namespace ");
555 text
.AppendLine (" {");
556 previous_namespace
= ns
;
561 if (type
.ContentProperty
!= null)
562 text
.AppendFormat ("\t[ContentProperty (\"{0}\")]\n", type
.ContentProperty
);
563 text
.Append ("\tpartial class ");
564 text
.Append (type
.ManagedName
.Replace ("`1", "<T>"));
565 text
.AppendLine (" {");
568 if (!string.IsNullOrEmpty (type
.C_Constructor
)) {
569 string access
= "Public";
570 foreach (MemberInfo member
in type
.Children
.Values
) {
571 MethodInfo method
= member
as MethodInfo
;
573 if (method
== null || !method
.IsConstructor
|| method
.IsStatic
)
576 if (method
.Parameters
.Count
!= 0)
579 if (method
.Annotations
.ContainsKey ("ManagedAccess"))
580 access
= method
.Annotations
.GetValue ("ManagedAccess");
585 text
.Append ("\t\t");
586 Helper
.WriteAccess (text
, access
);
588 text
.Append (type
.ManagedName
.Replace ("`1", ""));
589 text
.Append (" () : base (NativeMethods.");
590 text
.Append (type
.C_Constructor
);
591 text
.Append (" (), true)");
592 if (call_initialize
) {
594 text
.AppendLine ("\t\t{");
595 text
.AppendLine ("\t\t\tInitialize ();");
596 text
.AppendLine ("\t\t}");
598 text
.AppendLine (" {}");
603 text
.Append ("\t\tinternal ");
604 text
.Append (type
.ManagedName
.Replace ("`1", ""));
605 text
.Append (" (IntPtr raw, bool dropref) : base (raw, dropref)");
606 if (call_initialize
) {
608 text
.AppendLine ("\t\t{");
609 text
.AppendLine ("\t\t\tInitialize ();");
610 text
.AppendLine ("\t\t}");
612 text
.AppendLine (" {}");
615 text
.AppendLine ("\t}");
617 text
.AppendLine ("}");
619 Helper
.WriteAllText (filename
, text
.ToString ());
622 static void GenerateManagedDPs (GlobalInfo all
)
624 string base_dir
= Environment
.CurrentDirectory
;
625 string class_dir
= Path
.Combine (base_dir
, "class");
626 string sys_win_dir
= Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), "System.Windows");
627 string filename
= Path
.Combine (sys_win_dir
, "DependencyProperty.g.cs");
628 string previous_namespace
= "";
629 List
<TypeInfo
> sorted_types
= new List
<TypeInfo
> ();
630 StringBuilder text
= new StringBuilder ();
631 Dictionary
<TypeInfo
, List
<FieldInfo
>> types
= new Dictionary
<TypeInfo
,List
<FieldInfo
>> ();
633 foreach (FieldInfo field
in all
.DependencyProperties
) {
634 TypeInfo parent
= field
.Parent
as TypeInfo
;
635 List
<FieldInfo
> fields
;
636 string managed_parent
= field
.Annotations
.GetValue ("ManagedDeclaringType");
638 if (field
.Annotations
.GetValue ("GenerateManagedDP") == "false")
641 if (managed_parent
!= null) {
642 parent
= all
.Children
[managed_parent
] as TypeInfo
;
645 throw new Exception (string.Format ("Could not find the type '{0}' set as ManagedDeclaringType of '{1}'", managed_parent
, field
.FullName
));
649 throw new Exception (string.Format ("The field '{0}' does not have its parent set.", field
.FullName
));
651 if (!types
.TryGetValue (parent
, out fields
)) {
652 fields
= new List
<FieldInfo
> ();
653 types
.Add (parent
, fields
);
654 sorted_types
.Add (parent
);
659 Helper
.WriteWarningGenerated (text
);
660 text
.AppendLine ("using Mono;");
661 text
.AppendLine ("using System;");
662 text
.AppendLine ("using System.Collections.Generic;");
663 text
.AppendLine ("using System.Windows;");
664 text
.AppendLine ("using System.Windows.Controls;");
665 text
.AppendLine ("using System.Windows.Documents;");
666 text
.AppendLine ("using System.Windows.Ink;");
667 text
.AppendLine ("using System.Windows.Input;");
668 text
.AppendLine ("using System.Windows.Markup;");
669 text
.AppendLine ("using System.Windows.Media;");
670 text
.AppendLine ("using System.Windows.Media.Animation;");
671 text
.AppendLine ("using System.Windows.Media.Effects;");
672 text
.AppendLine ("using System.Windows.Shapes;");
675 sorted_types
.Sort (new Members
.MembersSortedByManagedFullName
<TypeInfo
> ());
676 for (int i
= 0; i
< sorted_types
.Count
; i
++) {
677 TypeInfo type
= sorted_types
[i
];
678 List
<FieldInfo
> fields
= types
[type
];
679 TypeInfo parent
= type
;
682 ns
= parent
.Namespace
;
684 if (string.IsNullOrEmpty (ns
)) {
685 Console
.WriteLine ("The type '{0}' in {1} does not have a namespace annotation.", parent
.FullName
, parent
.Header
);
689 if (type
.Annotations
.ContainsKey ("ManagedDependencyProperties")) {
690 string dp_mode
= type
.Annotations
.GetValue ("ManagedDependencyProperties");
698 throw new Exception (string.Format ("Invalid value '{0}' for ManagedDependencyProperties in '{1}'", dp_mode
, type
.FullName
));
703 Console
.WriteLine ("'{0}''s Namespace = 'None', this type should have set @ManagedDependencyProperties=Manual to not create DPs.", type
.FullName
);
707 string check_ns
= Path
.Combine (Path
.Combine (Path
.Combine (class_dir
, "System.Windows"), ns
), parent
.Name
+ ".cs");
708 if (!File
.Exists (check_ns
))
709 Console
.WriteLine ("The file {0} does not exist, did you annotate the class with the wrong namespace?", check_ns
);
711 if (previous_namespace
!= ns
) {
712 if (previous_namespace
!= string.Empty
) {
713 text
.AppendLine ("}");
716 text
.Append ("namespace ");
718 text
.AppendLine (" {");
719 previous_namespace
= ns
;
723 text
.Append ("\tpartial class ");
724 text
.Append (parent
.ManagedName
);
725 text
.AppendLine (" {");
727 fields
.Sort (new Members
.MembersSortedByName
<FieldInfo
> ());
729 // The DP registration
730 foreach (FieldInfo field
in fields
) {
731 bool conv_int_to_double
= field
.GetDPManagedPropertyType (all
) == "int" && field
.GetDPPropertyType (all
).Name
== "double";
733 text
.Append ("\t\t");
734 Helper
.WriteAccess (text
, field
.GetManagedFieldAccess ());
735 text
.Append (" static readonly DependencyProperty ");
736 text
.Append (field
.Name
);
737 text
.Append (" = DependencyProperty.Lookup (Kind.");
738 text
.Append (field
.ParentType
.KindName
);
739 text
.Append (", \"");
740 text
.Append (field
.GetDependencyPropertyName ());
741 text
.Append ("\", typeof (");
742 if (conv_int_to_double
)
743 text
.Append ("double");
745 text
.Append (field
.GetDPManagedPropertyType (all
));
746 text
.AppendLine ("));");
749 foreach (FieldInfo field
in fields
) {
750 bool conv_int_to_double
= field
.GetDPManagedPropertyType (all
) == "int" && field
.GetDPPropertyType (all
).Name
== "double";
752 if (field
.IsDPAttached
|| !field
.GenerateManagedAccessors
)
758 text
.Append ("\t\t");
759 Helper
.WriteAccess (text
, field
.GetManagedAccessorAccess ());
761 text
.Append (field
.GetDPManagedPropertyType (all
));
763 text
.Append (field
.GetDependencyPropertyName ());
764 text
.AppendLine (" {");
767 text
.Append ("\t\t\t");
768 if (field
.GetManagedAccessorAccess () != field
.GetManagedGetterAccess ()) {
769 Helper
.WriteAccess (text
, field
.GetManagedGetterAccess ());
773 text
.Append ("get { return (");
774 text
.Append (field
.GetDPManagedPropertyType (all
));
775 if (conv_int_to_double
)
776 text
.Append (") (double");
777 text
.Append (") GetValue (");
778 text
.Append (field
.Name
);
779 text
.AppendLine ("); }");
782 if (!field
.IsDPReadOnly
) {
783 text
.Append ("\t\t\t");
784 if (field
.GetManagedAccessorAccess () != field
.GetManagedSetterAccess ()) {
785 Helper
.WriteAccess (text
, field
.GetManagedSetterAccess ());
788 text
.Append ("set { SetValue (");
789 text
.Append (field
.Name
);
790 text
.AppendLine (", value); }");
792 text
.AppendLine ("\t\t}");
795 text
.AppendLine ("\t}");
797 text
.AppendLine ("}");
799 Helper
.WriteAllText (filename
, text
.ToString ());
802 class TypeEdgeCount
{
803 public TypeEdgeCount (TypeInfo type
)
806 Inbound
= new List
<TypeInfo
>();
807 Outbound
= new List
<TypeInfo
>();
810 public TypeInfo Type
{
813 public List
<TypeInfo
> Inbound
{
816 public List
<TypeInfo
> Outbound
{
821 static List
<FieldInfo
> TopoSortedProperties (GlobalInfo all
, List
<TypeInfo
> types
)
823 Dictionary
<TypeInfo
,TypeEdgeCount
> typeHash
= new Dictionary
<TypeInfo
,TypeEdgeCount
>();
825 List
<TypeInfo
> remainingTypes
= new List
<TypeInfo
>();
827 foreach (TypeInfo type
in types
) {
828 typeHash
.Add (type
, new TypeEdgeCount (type
));
829 remainingTypes
.Add (type
);
832 // build up edges for our graph
833 foreach (TypeInfo type
in typeHash
.Keys
) {
835 // every property defines an edge from the declaring type to the property type
836 foreach (FieldInfo prop
in type
.Properties
) {
837 if (string.IsNullOrEmpty (prop
.DPDefaultValue
))
840 TypeInfo propType
= prop
.GetDPPropertyType (all
);
841 if (propType
== type
)
843 if (typeHash
.ContainsKey (propType
) && !typeHash
[propType
].Inbound
.Contains (type
)) {
844 typeHash
[propType
].Inbound
.Add (type
);
845 typeHash
[type
].Outbound
.Add (propType
);
849 // every base class has an edge to subclass
850 // (this is kind of a hack to deal with
851 // property types which are listed as base
852 // types when the default values are
855 TypeInfo ourType
= type
;
856 TypeReference baseRef
= ourType
.Base
;
857 while (baseRef
!= null && !string.IsNullOrEmpty (baseRef
.Value
)) {
858 TypeInfo baseType
= (TypeInfo
) all
.Children
[baseRef
.Value
];
859 if (baseType
== null)
861 if (typeHash
.ContainsKey (baseType
) && !typeHash
[baseType
].Outbound
.Contains (ourType
)) {
862 typeHash
[baseType
].Outbound
.Add (ourType
);
863 typeHash
[ourType
].Inbound
.Add (baseType
);
866 if (!typeHash
.ContainsKey (ourType
))
868 baseRef
= ourType
.Base
;
872 List
<TypeInfo
> sorted
= new List
<TypeInfo
>();
873 List
<TypeInfo
> roots
= new List
<TypeInfo
>();
875 foreach (TypeEdgeCount tec
in typeHash
.Values
) {
876 if (tec
.Inbound
.Count
== 0)
877 roots
.Add (tec
.Type
);
880 while (roots
.Count
> 0) {
881 TypeInfo type
= roots
[0];
885 remainingTypes
.Remove (type
);
887 foreach (TypeInfo targetType
in typeHash
[type
].Outbound
) {
888 if (!typeHash
.ContainsKey (targetType
))
890 typeHash
[targetType
].Inbound
.Remove (type
);
891 if (typeHash
[targetType
].Inbound
.Count
== 0) {
892 roots
.Add (targetType
);
897 if (remainingTypes
.Count
> 0) {
898 throw new Exception (string.Format ("cycle in the DO/DP graph ({0} types left)", remainingTypes
.Count
));
901 List
<FieldInfo
> fields
= new List
<FieldInfo
>();
902 foreach (TypeInfo type
in sorted
) {
903 foreach (FieldInfo field
in type
.Properties
)
904 fields
.Insert (0, field
);
909 static void GenerateDPs (GlobalInfo all
)
911 string base_dir
= Environment
.CurrentDirectory
;
912 string moon_dir
= Path
.Combine (base_dir
, "src");
913 // int version_previous = 0;
914 StringBuilder text
= new StringBuilder ();
915 List
<FieldInfo
> fields
= all
.DependencyProperties
;
916 List
<string> headers
= new List
<string> ();
918 List
<TypeInfo
> types
= new List
<TypeInfo
> ();
919 foreach (FieldInfo field
in fields
) {
920 if (!types
.Contains ((TypeInfo
)field
.Parent
))
921 types
.Add ((TypeInfo
)field
.Parent
);
923 fields
= TopoSortedProperties (all
, types
);
925 headers
.Add ("dependencyproperty.h");
926 headers
.Add ("validators.h");
927 headers
.Add ("provider.h");
928 headers
.Add ("color.h");
929 foreach (FieldInfo field
in fields
) {
931 if (string.IsNullOrEmpty (field
.Header
))
933 h
= Path
.GetFileName (field
.Header
);
935 if (!headers
.Contains (h
))
939 Helper
.WriteWarningGenerated (text
);
941 text
.AppendLine ("#include <config.h>");
944 foreach (string h
in headers
) {
945 text
.Append ("#include \"");
947 text
.AppendLine ("\"");
950 text
.AppendLine ("void");
951 text
.AppendLine ("Types::RegisterNativeProperties ()");
952 text
.AppendLine ("{");
954 for (int i
= 0; i
< fields
.Count
; i
++) {
955 FieldInfo field
= fields
[i
];
956 TypeInfo type
= field
.ParentType
;
957 TypeInfo propertyType
= null;
958 string default_value
= field
.DPDefaultValue
;
959 bool has_default_value
= !string.IsNullOrEmpty (default_value
);
960 string autocreator
= field
.DPAutoCreator
;
961 bool is_nullable
= field
.IsDPNullable
;
962 bool is_attached
= field
.IsDPAttached
;
963 bool is_readonly
= field
.IsDPReadOnly
;
964 bool is_always_change
= field
.IsDPAlwaysChange
;
965 string validator
= field
.DPValidator
;
966 bool is_full
= is_attached
|| is_readonly
|| is_always_change
|| validator
!= null || autocreator
!= null || is_nullable
;
968 propertyType
= field
.GetDPPropertyType (all
);
972 if (propertyType
== null) {
973 text
.Append ("// (no PropertyType was found for this DependencyProperty) ");
975 headers
.Add (propertyType
.Header
);
978 text
.Append ("DependencyProperty::Register");
980 text
.Append ("Full");
983 text
.Append ("this, ");
984 text
.Append ("Type::");
985 text
.Append (type
.KindName
);
986 text
.Append (", \"");
988 text
.Append (field
.GetDependencyPropertyName ());
992 text
.Append (field
.IsCustom
? "true" : "false");
996 if (has_default_value
) {
997 if (default_value
.StartsWith ("new "))
998 text
.Append ("Value::CreateUnrefPtr (");
1000 text
.Append ("new Value (");
1001 text
.Append (default_value
);
1004 text
.Append ("NULL");
1007 if (has_default_value
) {
1008 if (default_value
.StartsWith ("new "))
1009 text
.Append ("Value::CreateUnrefPtr (");
1011 text
.Append ("new Value (");
1012 text
.Append (default_value
);
1017 if ((has_default_value
|| is_full
))
1020 if (propertyType
!= null) {
1021 if (propertyType
.IsEnum
) {
1022 text
.Append ("Type::INT32");
1024 text
.Append ("Type::");
1025 text
.Append (propertyType
.KindName
);
1027 } else if (!has_default_value
) {
1028 text
.Append ("Type::INVALID");
1029 Console
.WriteLine ("{0} does not define its property type.", field
.FullName
);
1034 text
.Append (is_attached
? "true" : "false");
1036 text
.Append (is_readonly
? "true" : "false");
1038 text
.Append (is_always_change
? "true" : "false");
1040 text
.Append ("NULL");
1042 text
.Append (validator
!= null ? ("Validators::" + validator
) : "NULL");
1044 text
.Append (autocreator
!= null
1045 ? (autocreator
.Contains("::") ? autocreator
: "AutoCreators::" + autocreator
)
1048 text
.Append (is_nullable
? "true" : "false");
1051 text
.AppendLine (");");
1053 text
.AppendLine ("}");
1056 // Static initializers
1057 for (int i
= 0; i
< fields
.Count
; i
++) {
1058 FieldInfo field
= fields
[i
];
1059 text
.Append ("const int ");
1060 text
.Append (field
.Parent
.Name
);
1062 text
.Append (field
.Name
);
1063 text
.Append (" = ");
1065 text
.AppendLine (";");
1070 for (int i
= 0; i
< fields
.Count
; i
++) {
1071 FieldInfo field
= fields
[i
];
1073 string prop_type_str
;
1075 string prop_default
= null;
1076 bool both
= field
.Annotations
.ContainsKey ("GenerateAccessors");
1077 bool setter
= both
|| field
.Annotations
.ContainsKey ("GenerateSetter");
1078 bool getter
= both
|| field
.Annotations
.ContainsKey ("GenerateGetter");
1079 bool is_attached
= field
.IsDPAttached
;
1080 bool nullable_setter
= setter
&& field
.IsDPNullable
;
1081 bool doing_nullable_setter
= false;
1083 if (!setter
&& !getter
)
1086 prop_type
= field
.GetDPPropertyType (all
);
1088 switch (prop_type
.Name
) {
1090 prop_type_str
= "const char *";
1091 value_str
= "String";
1095 value_str
= "Int32";
1096 prop_type_str
= prop_type
.Name
;
1100 value_str
= "Double";
1101 prop_type_str
= prop_type
.Name
;
1102 prop_default
= "0.0";
1105 prop_type_str
= prop_type
.Name
;
1107 prop_default
= "false";
1110 prop_type_str
= "gunichar";
1115 prop_type_str
= "Value *";
1116 prop_default
= "NULL";
1120 prop_type_str
= prop_type
.Name
;
1121 value_str
= prop_type
.Name
;
1125 string GetterName
= string.Format ("{0}::Get{1}", field
.ParentType
.Name
, field
.GetDependencyPropertyName());
1126 string SetterName
= string.Format ("{0}::Set{1}", field
.ParentType
.Name
, field
.GetDependencyPropertyName());
1129 text
.Append (prop_type_str
);
1130 if (field
.IsDPNullable
|| (prop_type
.IsClass
|| prop_type
.IsStruct
))
1133 text
.Append (GetterName
);
1135 text
.AppendLine (" (DependencyObject *obj)");
1137 text
.AppendLine (" ()");
1138 text
.AppendLine ("{");
1141 if (value_str
== null) {
1142 text
.Append ("\treturn ");
1143 } else if (is_attached
) {
1144 text
.Append ("\tValue *value = (!obj) ? NULL : ");
1146 text
.Append ("\tValue *value = ");
1149 text
.AppendFormat ("{0}{1}GetValue ({2}::{3});\n",
1150 is_attached
? "obj->" : "",
1151 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1152 field
.ParentType
.Name
, field
.Name
);
1155 text
.AppendFormat ("\tif (!value) value = Deployment::GetCurrent ()->GetTypes ()->GetProperty ({0}::{1})->GetDefaultValue();\n",
1156 field
.ParentType
.Name
, field
.Name
);
1159 if (value_str
== null) {
1161 } else if (field
.IsDPNullable
|| (prop_type
.IsClass
|| prop_type
.IsStruct
|| prop_type
.Name
== "char*")) {
1162 text
.Append ("\treturn value ? ");
1163 if (prop_type
.IsEnum
) {
1164 text
.AppendFormat ("({0}) value->AsInt32() : ({0}) 0", prop_type
.Name
);
1166 if (!field
.IsDPNullable
&& (/*prop_type.IsStruct || */prop_default
!= null))
1167 if (string.IsNullOrEmpty (prop_default
))
1168 throw new NotImplementedException (
1169 string.Format ("Generation of DependencyProperties with struct values ({0}.{1})",
1170 field
.ParentType
.Name
, field
.Name
));
1172 text
.AppendFormat ("value->As{0}{1} () : {2}",
1173 field
.IsDPNullable
&& !(prop_type
.IsStruct
|| prop_type
.IsClass
) ? "Nullable" : "",
1175 !field
.IsDPNullable
&& prop_default
!= null ? prop_default
: "NULL");
1178 // Value cannot be null, so don't need to check for it
1179 text
.Append ("\treturn ");
1180 if (prop_type
.IsEnum
) {
1181 text
.AppendFormat ("({0}) value->AsInt32 ()", prop_type
.Name
);
1183 text
.AppendFormat ("value->As{0} ()", value_str
);
1187 if (value_str
!= null)
1188 text
.AppendLine (";");
1189 text
.AppendLine ("}");
1195 text
.AppendLine ("void");
1196 text
.Append (SetterName
);
1199 text
.Append ("DependencyObject *obj, ");
1200 text
.Append (prop_type_str
);
1201 if (prop_type
.Name
!= "char*")
1203 if (!nullable_setter
&& (prop_type
.IsClass
|| prop_type
.IsStruct
))
1205 text
.AppendLine ("value)");
1207 text
.AppendLine ("{");
1209 text
.AppendLine ("\tif (!obj) return;");
1210 if (doing_nullable_setter
) {
1211 text
.AppendLine ("\tif (!value)");
1212 text
.Append ("\t\t");
1213 text
.AppendFormat ("{0}{1}SetValue ({2}::{3}, NULL);\n",
1214 is_attached
? "obj->" : "",
1215 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1216 field
.ParentType
.Name
, field
.Name
);
1217 text
.AppendLine ("\telse");
1218 text
.Append ("\t\t");
1219 text
.AppendFormat ("{0}{1}SetValue ({2}::{3}, Value (*value));\n",
1220 is_attached
? "obj->" : "",
1221 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1222 field
.ParentType
.Name
, field
.Name
);
1224 if (!nullable_setter
&& prop_type
.IsStruct
)
1225 text
.AppendLine ("\tif (!value) return;");
1227 text
.AppendFormat ("{0}{1}SetValue ({2}::{3}, ",
1228 is_attached
? "obj->" : "",
1229 field
.ParentType
.NeedsQualifiedGetValue(all
) ? "DependencyObject::" : "",
1230 field
.ParentType
.Name
, field
.Name
);
1232 if (prop_type
.Name
== "guint64" || prop_type
.Name
== "TimeSpan") {
1233 text
.AppendFormat ("Value (value, Type::{0}));\n",
1234 prop_type
.KindName
);
1236 else if (prop_type
.Name
== "char") {
1237 text
.AppendLine ("Value (value, Type::CHAR));");
1239 else if ((value_str
== null) || (!nullable_setter
&& prop_type
.IsStruct
)) {
1240 text
.AppendLine ("Value (*value));");
1242 else if (prop_type
.IsClass
) {
1243 text
.AppendLine ("Value::CreateUnrefPtr (value));");
1246 text
.AppendLine ("Value (value));");
1249 text
.AppendLine ("}");
1253 if (nullable_setter
) {
1254 if (!prop_type
.IsStruct
)
1255 prop_type_str
+= " *";
1256 nullable_setter
= false;
1257 doing_nullable_setter
= true;
1258 goto do_nullable_setter
;
1262 Helper
.WriteAllText (Path
.Combine (moon_dir
, "dependencyproperty.g.cpp"), text
.ToString ());
1266 static GlobalInfo
GetTypes2 ()
1268 string srcdir
= Path
.Combine (Environment
.CurrentDirectory
, "src");
1269 string asfdir
= Path
.Combine (srcdir
, "asf");
1270 string plugindir
= Path
.Combine (Environment
.CurrentDirectory
, "plugin");
1271 List
<string> all_files
= new List
<string> ();
1273 all_files
.AddRange (Directory
.GetFiles (srcdir
, "*.h"));
1274 all_files
.AddRange (Directory
.GetFiles (asfdir
, "*.h"));
1275 all_files
.AddRange (Directory
.GetFiles (plugindir
, "*.h"));
1277 RemoveExcludedSrcFiles (srcdir
, all_files
);
1279 Tokenizer tokenizer
= new Tokenizer (all_files
.ToArray ());
1280 GlobalInfo all
= new GlobalInfo ();
1282 tokenizer
.Advance (false);
1285 while (ParseMembers (all
, tokenizer
)) {
1287 } catch (Exception ex
) {
1288 throw new Exception (string.Format ("{0}({1}): {2}", tokenizer
.CurrentFile
, tokenizer
.CurrentLine
, ex
.Message
), ex
);
1291 // Add all the manual types
1293 TypeInfo IComparableInfo
;
1294 TypeInfo IFormattableInfo
;
1295 TypeInfo IConvertibleInfo
;
1296 TypeInfo IEquatableBoolInfo
;
1297 TypeInfo IComparableBoolInfo
;
1298 TypeInfo IEquatableDoubleInfo
;
1299 TypeInfo IComparableDoubleInfo
;
1300 TypeInfo IEquatableFloatInfo
;
1301 TypeInfo IComparableFloatInfo
;
1302 TypeInfo IEquatableCharInfo
;
1303 TypeInfo IComparableCharInfo
;
1304 TypeInfo IEquatableIntInfo
;
1305 TypeInfo IComparableIntInfo
;
1306 TypeInfo IEquatableLongInfo
;
1307 TypeInfo IComparableLongInfo
;
1308 TypeInfo IEquatableStringInfo
;
1309 TypeInfo IComparableStringInfo
;
1310 TypeInfo IEquatableTimeSpanInfo
;
1311 TypeInfo IComparableTimeSpanInfo
;
1312 TypeInfo IEquatableUintInfo
;
1313 TypeInfo IComparableUintInfo
;
1314 TypeInfo IEquatableUlongInfo
;
1315 TypeInfo IComparableUlongInfo
;
1317 all
.Children
.Add (new TypeInfo ("object", "OBJECT", "INVALID", true, true));
1319 all
.Children
.Add (IComparableInfo
= new TypeInfo ("IComparable", "ICOMPARABLE", "OBJECT", true, true, false, true));
1320 all
.Children
.Add (IFormattableInfo
= new TypeInfo ("IFormattable", "IFORMATTABLE", "OBJECT", true, true, false, true));
1321 all
.Children
.Add (IConvertibleInfo
= new TypeInfo ("IConvertible", "ICONVERTIBLE", "OBJECT", true, true, false, true));
1323 all
.Children
.Add (IEquatableBoolInfo
= new TypeInfo ("IEquatable<bool>", "IEQUATABLE_BOOL", "OBJECT", true, true, false, true));
1324 all
.Children
.Add (IComparableBoolInfo
= new TypeInfo ("IComparable<bool>", "ICOMPARABLE_BOOL", "OBJECT", true, true, false, true));
1326 all
.Children
.Add (IEquatableDoubleInfo
= new TypeInfo ("IEquatable<double>", "IEQUATABLE_DOUBLE", "OBJECT", true, true, false, true));
1327 all
.Children
.Add (IComparableDoubleInfo
= new TypeInfo ("IComparable<double>", "ICOMPARABLE_DOUBLE", "OBJECT", true, true, false, true));
1329 all
.Children
.Add (IEquatableFloatInfo
= new TypeInfo ("IEquatable<float>", "IEQUATABLE_FLOAT", "OBJECT", true, true, false, true));
1330 all
.Children
.Add (IComparableFloatInfo
= new TypeInfo ("IComparable<float>", "ICOMPARABLE_FLOAT", "OBJECT", true, true, false, true));
1332 all
.Children
.Add (IEquatableCharInfo
= new TypeInfo ("IEquatable<char>", "IEQUATABLE_CHAR", "OBJECT", true, true, false, true));
1333 all
.Children
.Add (IComparableCharInfo
= new TypeInfo ("IComparable<char>", "ICOMPARABLE_CHAR", "OBJECT", true, true, false, true));
1335 all
.Children
.Add (IEquatableIntInfo
= new TypeInfo ("IEquatable<int>", "IEQUATABLE_INT", "OBJECT", true, true, false, true));
1336 all
.Children
.Add (IComparableIntInfo
= new TypeInfo ("IComparable<int>", "ICOMPARABLE_INT", "OBJECT", true, true, false, true));
1338 all
.Children
.Add (IEquatableLongInfo
= new TypeInfo ("IEquatable<long>", "IEQUATABLE_LONG", "OBJECT", true, true, false, true));
1339 all
.Children
.Add (IComparableLongInfo
= new TypeInfo ("IComparable<long>", "ICOMPARABLE_LONG", "OBJECT", true, true, false, true));
1341 all
.Children
.Add (IEquatableStringInfo
= new TypeInfo ("IEquatable<string>", "IEQUATABLE_STRING", "OBJECT", true, true, false, true));
1342 all
.Children
.Add (IComparableStringInfo
= new TypeInfo ("IComparable<string>", "ICOMPARABLE_STRING", "OBJECT", true, true, false, true));
1344 all
.Children
.Add (IEquatableTimeSpanInfo
= new TypeInfo ("IEquatable<TimeSpan>", "IEQUATABLE_TIMESPAN", "OBJECT", true, true, false, true));
1345 all
.Children
.Add (IComparableTimeSpanInfo
= new TypeInfo ("IComparable<TimeSpan>", "ICOMPARABLE_TIMESPAN", "OBJECT", true, true, false, true));
1347 all
.Children
.Add (IEquatableUintInfo
= new TypeInfo ("IEquatable<uint>", "IEQUATABLE_UINT", "OBJECT", true, true, false, true));
1348 all
.Children
.Add (IComparableUintInfo
= new TypeInfo ("IComparable<uint>", "ICOMPARABLE_UINT", "OBJECT", true, true, false, true));
1350 all
.Children
.Add (IEquatableUlongInfo
= new TypeInfo ("IEquatable<ulong>", "IEQUATABLE_ULONG", "OBJECT", true, true, false, true));
1351 all
.Children
.Add (IComparableUlongInfo
= new TypeInfo ("IComparable<ulong>", "ICOMPARABLE_ULONG", "OBJECT", true, true, false, true));
1353 all
.Children
.Add (t
= new TypeInfo ("bool", "BOOL", "OBJECT", true, true, true, false));
1354 t
.Interfaces
.Add (IComparableInfo
);
1355 t
.Interfaces
.Add (IComparableBoolInfo
);
1356 t
.Interfaces
.Add (IConvertibleInfo
);
1357 t
.Interfaces
.Add (IEquatableBoolInfo
);
1359 all
.Children
.Add (t
= new TypeInfo ("float", "FLOAT", "OBJECT", true, true, true, false));
1360 t
.Interfaces
.Add (IComparableInfo
);
1361 t
.Interfaces
.Add (IComparableFloatInfo
);
1362 t
.Interfaces
.Add (IConvertibleInfo
);
1363 t
.Interfaces
.Add (IEquatableFloatInfo
);
1364 t
.Interfaces
.Add (IFormattableInfo
);
1366 all
.Children
.Add (t
= new TypeInfo ("double", "DOUBLE", "OBJECT", true, true, true, false));
1367 t
.Interfaces
.Add (IComparableInfo
);
1368 t
.Interfaces
.Add (IComparableDoubleInfo
);
1369 t
.Interfaces
.Add (IConvertibleInfo
);
1370 t
.Interfaces
.Add (IEquatableDoubleInfo
);
1371 t
.Interfaces
.Add (IFormattableInfo
);
1373 all
.Children
.Add (t
= new TypeInfo ("guint64", "UINT64", "OBJECT", true, true, true, false));
1374 t
.Interfaces
.Add (IComparableInfo
);
1375 t
.Interfaces
.Add (IComparableUlongInfo
);
1376 t
.Interfaces
.Add (IConvertibleInfo
);
1377 t
.Interfaces
.Add (IEquatableUlongInfo
);
1378 t
.Interfaces
.Add (IFormattableInfo
);
1380 all
.Children
.Add (t
= new TypeInfo ("gint64", "INT64", "OBJECT", true, true, true, false));
1381 t
.Interfaces
.Add (IComparableInfo
);
1382 t
.Interfaces
.Add (IComparableLongInfo
);
1383 t
.Interfaces
.Add (IConvertibleInfo
);
1384 t
.Interfaces
.Add (IEquatableLongInfo
);
1385 t
.Interfaces
.Add (IFormattableInfo
);
1387 all
.Children
.Add (t
= new TypeInfo ("guint32", "UINT32", "OBJECT", true, true, true, false));
1388 t
.Interfaces
.Add (IComparableInfo
);
1389 t
.Interfaces
.Add (IComparableUintInfo
);
1390 t
.Interfaces
.Add (IConvertibleInfo
);
1391 t
.Interfaces
.Add (IEquatableUintInfo
);
1392 t
.Interfaces
.Add (IFormattableInfo
);
1394 all
.Children
.Add (t
= new TypeInfo ("gint32", "INT32", "OBJECT", true, true, true, false));
1395 t
.Interfaces
.Add (IComparableInfo
);
1396 t
.Interfaces
.Add (IComparableIntInfo
);
1397 t
.Interfaces
.Add (IConvertibleInfo
);
1398 t
.Interfaces
.Add (IEquatableIntInfo
);
1399 t
.Interfaces
.Add (IFormattableInfo
);
1401 all
.Children
.Add (t
= new TypeInfo ("char*", "STRING", "OBJECT", true, true, true, false));
1402 t
.Interfaces
.Add (IComparableInfo
);
1403 t
.Interfaces
.Add (IComparableStringInfo
);
1404 t
.Interfaces
.Add (IConvertibleInfo
);
1405 t
.Interfaces
.Add (IEquatableStringInfo
);
1406 t
.Interfaces
.Add (IFormattableInfo
);
1408 all
.Children
.Add (t
= new TypeInfo ("TimeSpan", "TIMESPAN", "OBJECT", true, true, true, false));
1409 t
.Interfaces
.Add (IComparableInfo
);
1410 t
.Interfaces
.Add (IComparableTimeSpanInfo
);
1411 t
.Interfaces
.Add (IEquatableTimeSpanInfo
);
1413 all
.Children
.Add (t
= new TypeInfo ("char", "CHAR", "OBJECT", true, true, true, false));
1414 t
.Interfaces
.Add (IComparableInfo
);
1415 t
.Interfaces
.Add (IComparableCharInfo
);
1416 t
.Interfaces
.Add (IConvertibleInfo
);
1417 t
.Interfaces
.Add (IEquatableCharInfo
);
1419 all
.Children
.Add (new TypeInfo ("NPObj", "NPOBJ", "OBJECT", true, true, true, false));
1420 all
.Children
.Add (new TypeInfo ("Managed", "MANAGED", "OBJECT", true, 2, true));
1422 all
.Children
.Add (new TypeInfo ("System.Windows.Input.Cursor", "CURSOR", "OBJECT", true, true));
1423 all
.Children
.Add (new TypeInfo ("System.Windows.Markup.XmlLanguage", "XMLLANGUAGE", "OBJECT", true, true));
1425 // Set IncludeInKinds for all types which inherit from EventObject
1426 foreach (MemberInfo member
in all
.Children
.Values
) {
1427 TypeInfo type
= member
as TypeInfo
;
1430 if (type
.Name
== "EventObject")
1431 type
.Annotations
["IncludeInKinds"] = null;
1433 TypeReference bR
= type
.Base
;
1436 while (bR
!= null) {
1437 if (bR
.Value
== "EventObject") {
1438 member
.Annotations
["IncludeInKinds"] = null;
1441 if (!all
.Children
.TryGetValue (bR
.Value
, out m
))
1455 // Returns false if there are no more tokens (reached end of code)
1456 static bool ParseClassOrStruct (Annotations annotations
, MemberInfo parent
, Tokenizer tokenizer
)
1458 TypeInfo type
= new TypeInfo ();
1460 type
.Annotations
= annotations
;
1461 type
.Header
= tokenizer
.CurrentFile
;
1462 type
.Parent
= parent
;
1464 type
.IsPublic
= tokenizer
.Accept (Token2Type
.Identifier
, "public");
1466 if (tokenizer
.Accept (Token2Type
.Identifier
, "class")) {
1467 type
.IsClass
= true;
1468 } else if (tokenizer
.Accept (Token2Type
.Identifier
, "struct")) {
1469 type
.IsStruct
= true;
1470 type
.IsValueType
= true;
1471 } else if (tokenizer
.Accept (Token2Type
.Identifier
, "union")) {
1472 type
.IsStruct
= true; // Not entirely correct, but a union can be parsed as a struct
1473 type
.IsValueType
= true;
1475 throw new Exception (string.Format ("Expected 'class' or 'struct', not '{0}'", tokenizer
.CurrentToken
.value));
1478 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1479 type
.Name
= tokenizer
.GetIdentifier ();
1481 type
.Name
= "<anonymous>";
1484 if (tokenizer
.Accept (Token2Type
.Punctuation
, ";")) {
1485 // A forward declaration.
1486 //Console.WriteLine ("ParseType: Found a forward declaration to {0}", type.Name);
1490 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1491 if (!tokenizer
.Accept (Token2Type
.Identifier
, "public") && type
.IsClass
)
1492 throw new Exception (string.Format ("The base class of {0} is not public.", type
.Name
));
1494 type
.Base
= ParseTypeReference (tokenizer
);
1496 // accept multiple inheritance the easy way
1497 while (tokenizer
.CurrentToken
.value == ",") {
1498 tokenizer
.Accept (Token2Type
.Punctuation
, ",");
1500 while (tokenizer
.CurrentToken
.value != "," &&
1501 tokenizer
.CurrentToken
.value != "{")
1502 tokenizer
.GetIdentifier ();
1505 //Console.WriteLine ("ParseType: Found {0}'s base class: {1}", type.Name, type.Base);
1508 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "{");
1510 //Console.WriteLine ("ParseType: Found a type: {0} in {1}", type.Name, type.Header);
1511 parent
.Children
.Add (type
);
1512 ParseMembers (type
, tokenizer
);
1514 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "}");
1516 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
)
1517 tokenizer
.Advance (true);
1519 if (tokenizer
.CurrentToken
.value != ";")
1520 throw new Exception (string.Format ("Expected ';', not '{0}'", tokenizer
.CurrentToken
.value));
1522 return tokenizer
.Advance (false);
1525 static bool ParseMembers (MemberInfo parent
, Tokenizer tokenizer
)
1527 Annotations properties
= new Annotations ();
1528 TypeInfo parent_type
= parent
as TypeInfo
;
1529 string accessibility
;
1530 TypeReference returntype
;
1539 //Console.WriteLine ("ParseMembers ({0})", type.Name);
1543 is_dtor
= is_ctor
= is_virtual
= is_static
= false;
1544 is_extern
= is_const
= false;
1546 properties
= new Annotations ();
1548 if (parent_type
!= null)
1549 accessibility
= parent_type
.IsStruct
? "public" : "private";
1551 accessibility
= "public";
1553 if (tokenizer
.Accept (Token2Type
.Punctuation
, ";"))
1556 if (tokenizer
.CurrentToken
.value == "}")
1559 while (tokenizer
.CurrentToken
.type
== Token2Type
.CommentProperty
) {
1560 properties
.Add (tokenizer
.CurrentToken
.value);
1561 tokenizer
.Advance (true);
1564 //Console.WriteLine ("ParseMembers: Current token: {0}", tokenizer.CurrentToken);
1566 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1567 string v
= tokenizer
.CurrentToken
.value;
1573 tokenizer
.Advance (true);
1574 tokenizer
.Accept (Token2Type
.Punctuation
, ":");
1577 ParseEnum (properties
, parent
, tokenizer
);
1580 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ";")) {
1581 tokenizer
.Advance (true);
1587 if (!ParseClassOrStruct (properties
, parent
, tokenizer
))
1591 StringBuilder requisite
= new StringBuilder ();
1592 requisite
.Append (tokenizer
.CurrentToken
.value);
1593 requisite
.Append (' ');
1594 tokenizer
.Advance (true);
1595 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ";")) {
1596 requisite
.Append (tokenizer
.CurrentToken
.value);
1597 requisite
.Append (' ');
1598 if (tokenizer
.CurrentToken
.value == "{") {
1599 tokenizer
.Advance (true);
1600 while (!tokenizer
.Accept (Token2Type
.Punctuation
, "}")) {
1601 requisite
.Append (tokenizer
.CurrentToken
.value);
1602 requisite
.Append (' ');
1603 tokenizer
.Advance (true);
1605 requisite
.Append (tokenizer
.CurrentToken
.value);
1606 requisite
.Append (' ');
1608 tokenizer
.Advance (true);
1610 requisite
.Append (";");
1611 if (properties
.ContainsKey ("CBindingRequisite"))
1612 cbinding_requisites
.AppendLine (requisite
.ToString ());
1615 case "EVENTHANDLER":
1616 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ";"))
1617 tokenizer
.Advance (true);
1620 tokenizer
.Advance (true);
1621 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "<");
1622 tokenizer
.AcceptOrThrow (Token2Type
.Identifier
, "typename");
1623 tokenizer
.GetIdentifier ();
1624 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ">");
1630 if (tokenizer
.Accept (Token2Type
.Identifier
, "virtual")) {
1635 if (tokenizer
.Accept (Token2Type
.Identifier
, "static")) {
1640 if (tokenizer
.Accept (Token2Type
.Identifier
, "const")) {
1645 if (tokenizer
.Accept (Token2Type
.Identifier
, "extern")) {
1650 if (tokenizer
.Accept (Token2Type
.Identifier
, "volatile")) {
1654 if (tokenizer
.Accept (Token2Type
.Identifier
, "G_GNUC_INTERNAL")) {
1661 if (is_extern
&& tokenizer
.Accept (Token2Type
.Literal
, "C")) {
1662 tokenizer
.SyncWithEndBrace ();
1666 if (tokenizer
.Accept (Token2Type
.Punctuation
, "~")) {
1669 TypeInfo ti
= parent
as TypeInfo
;
1670 if (ti
!= null && ti
.Base
!= null)
1671 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>");
1676 name
= "~" + tokenizer
.GetIdentifier ();
1677 returntype
= new TypeReference ("void");
1679 returntype
= ParseTypeReference (tokenizer
);
1681 if (tokenizer
.CurrentToken
.value == "<") {
1682 tokenizer
.Advance (true);
1683 while (!tokenizer
.Accept (Token2Type
.Punctuation
, ">"))
1684 tokenizer
.Advance (true);
1687 if (returntype
.Value
== parent
.Name
&& tokenizer
.CurrentToken
.value == "(") {
1689 name
= returntype
.Value
;
1690 returntype
.Value
+= "*";
1692 name
= tokenizer
.GetIdentifier ();
1695 returntype
.IsConst
= is_const
;
1696 returntype
.IsReturnType
= true;
1698 //Console.WriteLine ("ParseMembers: found member '{0}' is_ctor: {1}", name, is_ctor);
1700 if (tokenizer
.Accept (Token2Type
.Punctuation
, "(")) {
1702 MethodInfo method
= new MethodInfo ();
1703 method
.Header
= tokenizer
.CurrentFile
;
1704 method
.Parent
= parent
;
1705 method
.Annotations
= properties
;
1707 method
.IsConstructor
= is_ctor
;
1708 method
.IsDestructor
= is_dtor
;
1709 method
.IsVirtual
= is_virtual
;
1710 method
.IsStatic
= is_static
;
1711 method
.IsPublic
= accessibility
== "public";
1712 method
.IsPrivate
= accessibility
== "private";
1713 method
.IsProtected
= accessibility
== "protected";
1714 method
.ReturnType
= returntype
;
1716 //Console.WriteLine ("ParseMembers: found method '{0}' is_ctor: {1}", name, is_ctor);
1718 if (!tokenizer
.Accept (Token2Type
.Punctuation
, ")")) {
1719 string param_value
= null;
1721 ParameterInfo parameter
= new ParameterInfo (method
);
1723 while (tokenizer
.CurrentToken
.type
== Token2Type
.CommentProperty
) {
1724 parameter
.Annotations
.Add (tokenizer
.CurrentToken
.value);
1725 tokenizer
.Advance (true);
1728 if (tokenizer
.Accept (Token2Type
.Punctuation
, ".") && tokenizer
.Accept (Token2Type
.Punctuation
, ".") && tokenizer
.Accept (Token2Type
.Punctuation
, ".")) {
1729 // ... variable argument declaration
1730 parameter
.ParameterType
= new TypeReference ("...");
1732 parameter
.ParameterType
= ParseTypeReference (tokenizer
);
1734 if (tokenizer
.CurrentToken
.value != "," && tokenizer
.CurrentToken
.value != ")") {
1735 parameter
.Name
= tokenizer
.GetIdentifier ();
1736 if (tokenizer
.Accept (Token2Type
.Punctuation
, "[")) {
1737 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
)
1738 tokenizer
.Advance (true);
1739 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "]");
1741 if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1742 param_value
= string.Empty
;
1743 if (tokenizer
.Accept (Token2Type
.Punctuation
, "-"))
1745 param_value
+= tokenizer
.GetIdentifier ();
1746 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1747 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ":");
1748 param_value
+= "::" + tokenizer
.GetIdentifier ();
1752 method
.Parameters
.Add (parameter
);
1753 //Console.WriteLine ("ParseMember: got parameter, type: '{0}' name: '{1}' value: '{2}'", parameter.ParameterType.Value, parameter.Name, param_value);
1754 } while (tokenizer
.Accept (Token2Type
.Punctuation
, ","));
1755 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ")");
1758 parent
.Children
.Add (method
);
1760 //Allow const member functions, ignore the const keyword
1761 tokenizer
.Accept (Token2Type
.Identifier
, "const");
1763 if (tokenizer
.CurrentToken
.value == "{") {
1764 //Console.WriteLine ("ParseMember: member has body, skipping it");
1765 tokenizer
.SyncWithEndBrace ();
1766 } else if (is_ctor
&& tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1767 // ctor method implemented in header with field initializers and/or base class ctor call
1768 tokenizer
.FindStartBrace ();
1769 tokenizer
.SyncWithEndBrace ();
1770 //Console.WriteLine ("ParseMember: skipped ctor method implementation");
1771 } else if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1772 // pure virtual method
1773 tokenizer
.AcceptOrThrow (Token2Type
.Identifier
, "0");
1774 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ";");
1775 method
.IsAbstract
= true;
1777 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ";");
1780 if (is_ctor
|| is_dtor
)
1781 throw new Exception (string.Format ("Expected '(', not '{0}'", tokenizer
.CurrentToken
.value));
1783 if (name
== "operator") {
1785 if (tokenizer
.CurrentToken
.value == ";") {
1788 } else if (tokenizer
.CurrentToken
.value == "{") {
1789 // In-line implementation
1790 tokenizer
.SyncWithEndBrace ();
1793 tokenizer
.Advance (true);
1795 //Console.WriteLine ("ParseMembers: skipped operator");
1797 FieldInfo field
= new FieldInfo ();
1798 field
.IsConst
= is_const
;
1799 field
.IsStatic
= is_static
;
1800 field
.IsExtern
= is_extern
;
1802 field
.FieldType
= returntype
;
1803 field
.IsPublic
= accessibility
== "public";
1804 field
.IsPrivate
= accessibility
== "private";
1805 field
.IsProtected
= accessibility
== "protected";
1806 field
.Annotations
= properties
;
1810 //Console.WriteLine ("ParseMembers: found field '{0}'", name);
1811 field
.Parent
= parent
;
1812 parent
.Children
.Add (field
);
1814 if (tokenizer
.Accept (Token2Type
.Punctuation
, "[")) {
1815 while (!tokenizer
.Accept (Token2Type
.Punctuation
, "]")) {
1816 tokenizer
.Advance (true);
1819 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1820 field
.BitField
= tokenizer
.GetIdentifier ();
1822 if (tokenizer
.Accept (Token2Type
.Punctuation
, ",")) {
1823 field
= new FieldInfo ();
1824 if (tokenizer
.Accept (Token2Type
.Punctuation
, "*")) {
1827 field
.Name
= tokenizer
.GetIdentifier ();
1828 field
.FieldType
= returntype
;
1831 if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1832 tokenizer
.Advance (true); /* this can be an arbitrary long expression, sync with the ';'? */
1837 tokenizer
.Accept (Token2Type
.Punctuation
, ";");
1843 static void ParseEnum (Annotations properties
, MemberInfo parent
, Tokenizer tokenizer
)
1846 StringBuilder
value = new StringBuilder ();
1847 TypeInfo type
= new TypeInfo ();
1849 type
.Annotations
= properties
;
1852 tokenizer
.AcceptOrThrow (Token2Type
.Identifier
, "enum");
1853 if (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1854 type
.Name
= tokenizer
.GetIdentifier ();
1856 type
.Name
= "<anonymous>";
1858 parent
.Children
.Add (type
);
1860 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "{");
1862 //Console.WriteLine ("ParseEnum: {0}", name);
1864 while (tokenizer
.CurrentToken
.type
== Token2Type
.Identifier
) {
1865 field
= new FieldInfo ();
1866 field
.Name
= tokenizer
.GetIdentifier ();
1868 if (tokenizer
.Accept (Token2Type
.Punctuation
, "=")) {
1869 while (tokenizer
.CurrentToken
.value != "," && tokenizer
.CurrentToken
.value != "}") {
1871 value.Append (tokenizer
.CurrentToken
.value);
1872 tokenizer
.Advance (true);
1875 field
.Value
= value.ToString ();
1876 type
.Children
.Add (field
);
1877 //Console.WriteLine ("ParseEnum: {0}: {1} {2} {3}", name, field, value.Length != 0 != null ? "=" : "", value);
1879 if (!tokenizer
.Accept (Token2Type
.Punctuation
, ","))
1883 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, "}");
1884 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ";");
1887 public static TypeReference
ParseTypeReference (Tokenizer tokenizer
)
1889 TypeReference tr
= new TypeReference ();
1890 StringBuilder result
= new StringBuilder ();
1892 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1895 if (tokenizer
.Accept (Token2Type
.Identifier
, "unsigned"))
1896 result
.Append ("unsigned");
1898 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1901 result
.Append (tokenizer
.GetIdentifier ());
1903 if (tokenizer
.Accept (Token2Type
.Punctuation
, ":")) {
1904 tokenizer
.AcceptOrThrow (Token2Type
.Punctuation
, ":");
1905 result
.Append ("::");
1906 result
.Append (tokenizer
.GetIdentifier ());
1909 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1912 while (tokenizer
.Accept (Token2Type
.Punctuation
, "*"))
1913 result
.Append ("*");
1915 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1918 if (tokenizer
.Accept (Token2Type
.Punctuation
, "&"))
1919 result
.Append ("&");
1921 if (tokenizer
.Accept (Token2Type
.Identifier
, "const"))
1924 //Console.WriteLine ("ParseTypeReference: parsed '{0}'", result.ToString ());
1926 tr
.Value
= result
.ToString ();
1931 public static string getU (string v
)
1933 if (v
.Contains ("::"))
1934 v
= v
.Substring (v
.IndexOf ("::") + 2);
1937 v
= v
.Replace ("DEPENDENCYOBJECT", "DEPENDENCY_OBJECT");
1938 if (v
.Length
> "COLLECTION".Length
&& !v
.StartsWith ("COLLECTION"))
1939 v
= v
.Replace ("COLLECTION", "_COLLECTION");
1940 if (v
.Length
> "DICTIONARY".Length
)
1941 v
= v
.Replace ("DICTIONARY", "_DICTIONARY");
1945 public void GenerateTypes_G (GlobalInfo all
)
1947 string base_dir
= Environment
.CurrentDirectory
;
1948 string class_dir
= Path
.Combine (base_dir
, "class");
1949 string moon_moonlight_dir
= Path
.Combine (class_dir
, "System.Windows");
1950 List
<TypeInfo
> types
= new List
<TypeInfo
> (all
.GetDependencyObjects ());
1952 StringBuilder text
= new StringBuilder ();
1954 Helper
.WriteWarningGenerated (text
);
1956 text
.AppendLine ("using Mono;");
1957 text
.AppendLine ("using System;");
1958 text
.AppendLine ("using System.Reflection;");
1959 text
.AppendLine ("using System.Collections.Generic;");
1960 text
.AppendLine ("");
1961 text
.AppendLine ("namespace Mono {");
1962 text
.AppendLine ("\tpartial class Types {");
1963 text
.AppendLine ("\t\tprivate void CreateNativeTypes ()");
1964 text
.AppendLine ("\t\t{");
1965 text
.AppendLine ("\t\t\tType t;");
1966 text
.AppendLine ("\t\t\ttry {");
1968 foreach (MemberInfo m
in all
.Children
.Values
) {
1969 TypeInfo t
= m
as TypeInfo
;
1972 if (types
.Contains (t
))
1977 types
.Sort (new Members
.MembersSortedByManagedFullName
<TypeInfo
> ());
1979 for (int i
= 0; i
< types
.Count
; i
++) {
1980 TypeInfo t
= types
[i
];
1981 string type
= t
.ManagedName
;
1983 if (String
.IsNullOrEmpty (t
.Namespace
) || t
.Namespace
== "None" || t
.Name
.StartsWith ("MoonWindow"))
1986 if (type
== "PresentationFrameworkCollection`1")
1987 type
= "PresentationFrameworkCollection<>";
1989 //Log.WriteLine ("Found Kind.{0} in {1} which result in type: {2}.{3}", kind, file, ns, type);
1991 text
.Append ("\t\t\t\tt = typeof (");
1992 text
.Append (t
.Namespace
);
1995 text
.AppendLine ("); ");
1997 text
.Append ("\t\t\t\ttypes.Add (t, new ManagedType (t, Kind.");
1998 text
.Append (t
.KindName
);
1999 text
.AppendLine ("));");
2002 // now handle the primitive types
2003 output_native_type_delegate f
= delegate (string t
, string k
) {
2004 text
.Append ("\t\t\t\tt = typeof (");
2006 text
.AppendLine (");");
2009 text
.Append ("\t\t\t\ttypes.Add (t, new ManagedType (t, Kind.");
2011 text
.AppendLine ("));");
2014 f ("char", "UINT32");
2015 f ("object", "OBJECT");
2017 f ("double", "DOUBLE");
2018 f ("float", "FLOAT");
2019 f ("ulong", "UINT64");
2020 f ("long", "INT64");
2021 f ("uint", "UINT32");
2023 f ("string", "STRING");
2024 f ("TimeSpan", "TIMESPAN");
2026 // all the interfaces
2027 f ("IComparable", "ICOMPARABLE");
2028 f ("IFormattable", "IFORMATTABLE");
2029 f ("IConvertible", "ICONVERTIBLE");
2030 f ("IEquatable<bool>", "IEQUATABLE_BOOL");
2031 f ("IComparable<bool>", "ICOMPARABLE_BOOL");
2032 f ("IEquatable<double>", "IEQUATABLE_DOUBLE");
2033 f ("IComparable<double>", "ICOMPARABLE_DOUBLE");
2034 f ("IEquatable<float>", "IEQUATABLE_FLOAT");
2035 f ("IComparable<float>", "ICOMPARABLE_FLOAT");
2036 f ("IEquatable<char>", "IEQUATABLE_CHAR");
2037 f ("IComparable<char>", "ICOMPARABLE_CHAR");
2038 f ("IEquatable<int>", "IEQUATABLE_INT");
2039 f ("IComparable<int>", "ICOMPARABLE_INT");
2040 f ("IEquatable<long>", "IEQUATABLE_LONG");
2041 f ("IComparable<long>", "ICOMPARABLE_LONG");
2042 f ("IEquatable<string>", "IEQUATABLE_STRING");
2043 f ("IComparable<string>", "ICOMPARABLE_STRING");
2044 f ("IEquatable<TimeSpan>", "IEQUATABLE_TIMESPAN");
2045 f ("IComparable<TimeSpan>", "ICOMPARABLE_TIMESPAN");
2046 f ("IEquatable<uint>", "IEQUATABLE_UINT");
2047 f ("IComparable<uint>", "ICOMPARABLE_UINT");
2048 f ("IEquatable<ulong>", "IEQUATABLE_ULONG");
2049 f ("IComparable<ulong>", "ICOMPARABLE_ULONG");
2051 f ("System.Windows.Application", "APPLICATION");
2052 f ("System.Windows.Thickness", "THICKNESS");
2053 f ("System.Windows.CornerRadius", "CORNERRADIUS");
2054 f ("System.Windows.PropertyPath", "PROPERTYPATH");
2055 f ("System.Windows.Point", "POINT");
2056 f ("System.Windows.Rect", "RECT");
2057 f ("System.Windows.Size", "SIZE");
2058 f ("System.Windows.FontStretch", "FONTSTRETCH");
2059 f ("System.Windows.FontWeight", "FONTWEIGHT");
2060 f ("System.Windows.FontStyle", "FONTSTYLE");
2061 f ("System.Windows.Input.Cursor", "CURSOR");
2062 f ("System.Windows.Media.FontFamily", "FONTFAMILY");
2063 f ("System.Windows.Markup.XmlLanguage", "XMLLANGUAGE");
2065 text
.AppendLine ("\t\t\t} catch (Exception ex) {");
2066 text
.AppendLine ("\t\t\t\tConsole.WriteLine (\"There was an error while loading native types: \" + ex.ToString ());");
2067 text
.AppendLine ("\t\t\t}");
2068 text
.AppendLine ("\t\t}");
2069 text
.AppendLine ("\t}");
2070 text
.AppendLine ("}");
2072 Log
.WriteLine ("typeandkidngen done");
2074 Helper
.WriteAllText (Path
.Combine (Path
.Combine (moon_moonlight_dir
, "Mono"), "Types.g.cs"), text
.ToString ());
2077 private static void GenerateCBindings (GlobalInfo info
, string dir
)
2079 List
<MethodInfo
> methods
;
2080 StringBuilder header
= new StringBuilder ();
2081 StringBuilder impl
= new StringBuilder ();
2082 List
<string> headers
= new List
<string> ();
2083 List
<string> classes
= new List
<string> ();
2084 List
<string> structs
= new List
<string> ();
2086 string last_type
= string.Empty
;
2088 methods
= info
.CPPMethodsToBind
;
2090 Helper
.WriteWarningGenerated (header
);;
2091 Helper
.WriteWarningGenerated (impl
);
2093 header
.AppendLine ("#ifndef __MOONLIGHT_C_BINDING_H__");
2094 header
.AppendLine ("#define __MOONLIGHT_C_BINDING_H__");
2095 header
.AppendLine ();
2096 header
.AppendLine ("#include <glib.h>");
2097 header
.AppendLine ("#include <cairo.h>");
2098 header
.AppendLine ();
2099 header
.AppendLine ("#include \"enums.h\"");
2100 header
.AppendLine ();
2101 foreach (MemberInfo member
in info
.Children
.Values
) {
2102 TypeInfo type
= member
as TypeInfo
;
2107 if (!classes
.Contains (type
.Name
))
2108 classes
.Add (type
.Name
);
2109 } else if (type
.IsStruct
) {
2110 if (!structs
.Contains (type
.Name
))
2111 structs
.Add (type
.Name
);
2115 foreach (MemberInfo method
in methods
) {
2118 if (method
.ParentType
!= null) {
2119 TypeInfo type
= method
.ParentType
;
2121 if (!classes
.Contains (type
.Name
))
2122 classes
.Add (type
.Name
);
2123 } else if (type
.IsStruct
) {
2124 if (!structs
.Contains (type
.Name
))
2125 structs
.Add (type
.Name
);
2129 if (string.IsNullOrEmpty (method
.Header
))
2131 if (!method
.Header
.StartsWith (dir
))
2134 h
= Path
.GetFileName (method
.Header
);
2136 if (!headers
.Contains (h
))
2139 header
.AppendLine (forward_decls
.ToString ());
2142 foreach (string c
in classes
) {
2143 header
.Append ("class ");
2145 header
.AppendLine (";");
2147 header
.AppendLine ();
2148 foreach (string s
in structs
) {
2149 header
.Append ("struct ");
2151 header
.AppendLine (";");
2153 header
.AppendLine ();
2154 header
.AppendLine (cbinding_requisites
.ToString ());
2156 header
.AppendLine ();
2157 header
.AppendLine ("G_BEGIN_DECLS");
2158 header
.AppendLine ();
2160 impl
.AppendLine ("#include <config.h>");
2162 impl
.AppendLine ("#include <stdio.h>");
2163 impl
.AppendLine ("#include <stdlib.h>");
2165 impl
.AppendLine ("#include \"cbinding.h\"");
2168 foreach (string h
in headers
) {
2169 impl
.Append ("#include \"");
2171 impl
.AppendLine ("\"");
2174 foreach (MemberInfo member
in methods
) {
2175 MethodInfo method
= (MethodInfo
) member
;
2177 if (!method
.Header
.StartsWith (dir
))
2180 if (last_type
!= method
.Parent
.Name
) {
2181 last_type
= method
.Parent
.Name
;
2182 foreach (StringBuilder text
in new StringBuilder
[] {header, impl}
) {
2183 text
.AppendLine ("/**");
2184 text
.Append (" * ");
2185 text
.AppendLine (last_type
);
2186 text
.AppendLine (" **/");
2190 WriteHeaderMethod (method
.CMethod
, method
, header
, info
);
2191 header
.AppendLine ();
2193 WriteImplMethod (method
.CMethod
, method
, impl
, info
);
2198 header
.AppendLine ();
2199 header
.AppendLine ("G_END_DECLS");
2200 header
.AppendLine ();
2201 header
.AppendLine ("#endif");
2203 Helper
.WriteAllText (Path
.Combine (dir
, "cbinding.h"), header
.ToString ());
2204 Helper
.WriteAllText (Path
.Combine (dir
, "cbinding.cpp"), impl
.ToString ());
2207 public static void GenerateCBindings (GlobalInfo info
)
2209 string base_dir
= Environment
.CurrentDirectory
;
2210 string plugin_dir
= Path
.Combine (base_dir
, "plugin");
2211 string moon_dir
= Path
.Combine (base_dir
, "src");
2213 GenerateCBindings (info
, moon_dir
);
2214 GenerateCBindings (info
, plugin_dir
);
2217 static void WriteHeaderMethod (MethodInfo cmethod
, MethodInfo cppmethod
, StringBuilder text
, GlobalInfo info
)
2219 Log
.WriteLine ("Writing header: {0}::{1} (Version: '{2}', GenerateManaged: {3})",
2220 cmethod
.Parent
.Name
, cmethod
.Name
,
2221 cmethod
.Annotations
.GetValue ("Version"),
2222 cmethod
.Annotations
.ContainsKey ("GenerateManaged"));
2224 if (cmethod
.Annotations
.ContainsKey ("GeneratePInvoke"))
2225 text
.AppendLine ("/* @GeneratePInvoke */");
2226 cmethod
.ReturnType
.Write (text
, SignatureType
.NativeC
, info
);
2227 if (!cmethod
.ReturnType
.IsPointer
)
2229 text
.Append (cmethod
.Name
);
2230 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, false);
2231 text
.AppendLine (";");
2234 static void WriteImplMethod (MethodInfo cmethod
, MethodInfo cppmethod
, StringBuilder text
, GlobalInfo info
)
2236 bool is_void
= cmethod
.ReturnType
.Value
== "void";
2237 bool is_ctor
= cmethod
.IsConstructor
;
2238 bool is_static
= cmethod
.IsStatic
;
2239 bool is_dtor
= cmethod
.IsDestructor
;
2240 bool check_instance
= !is_static
&& !is_ctor
;
2241 bool check_error
= false;
2243 foreach (ParameterInfo parameter
in cmethod
.Parameters
) {
2244 if (parameter
.ParameterType
.Value
== "MoonError*") {
2250 cmethod
.ReturnType
.Write (text
, SignatureType
.NativeC
, info
);
2252 text
.Append (cmethod
.Name
);
2253 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, false);
2254 text
.AppendLine ("");
2255 text
.AppendLine ("{");
2258 text
.Append ("\treturn new ");
2259 text
.Append (cmethod
.Parent
.Name
);
2260 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, true);
2261 text
.AppendLine (";");
2262 } else if (is_dtor
) {
2263 text
.AppendLine ("\tdelete instance;");
2265 if (check_instance
) {
2266 text
.AppendLine ("\tif (instance == NULL)");
2268 if (cmethod
.ReturnType
.Value
== "void") {
2269 text
.Append ("\t\treturn");
2270 } else if (cmethod
.ReturnType
.Value
.Contains ("*")) {
2271 text
.Append ("\t\treturn NULL");
2272 } else if (cmethod
.ReturnType
.Value
== "Type::Kind") {
2273 text
.Append ("\t\treturn Type::INVALID");
2274 } else if (cmethod
.ReturnType
.Value
== "bool") {
2275 text
.Append ("\t\treturn false");
2276 } else if (cmethod
.ReturnType
.Value
== "Point") {
2277 text
.Append ("\t\treturn Point (0, 0)");
2279 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.");
2280 text
.Append ("\t\treturn");
2282 text
.Append (cmethod
.ReturnType
.Value
);
2283 text
.Append (") 0");
2285 text
.AppendLine (";");
2287 text
.AppendLine ("\t");
2291 text
.AppendLine ("\tif (error == NULL)");
2292 text
.Append ("\t\tg_warning (\"Moonlight: Called ");
2293 text
.Append (cmethod
.Name
);
2294 text
.AppendLine (" () with error == NULL.\");");
2299 text
.Append ("return ");
2302 text
.Append (cmethod
.Parent
.Name
);
2305 text
.Append ("instance->");
2306 cmethod
.Parameters
[0].DisableWriteOnce
= true;
2308 text
.Append (cppmethod
.Name
);
2309 cmethod
.Parameters
.Write (text
, SignatureType
.NativeC
, true);
2310 text
.AppendLine (";");
2313 text
.AppendLine ("}");
2316 static void GenerateTypeStaticCpp (GlobalInfo all
)
2319 List
<string> headers
= new List
<string> ();
2321 StringBuilder text
= new StringBuilder ();
2323 Helper
.WriteWarningGenerated (text
);
2325 text
.AppendLine ("#include <config.h>");
2327 text
.AppendLine ("#include <stdlib.h>");
2329 headers
.Add ("cbinding.h");
2330 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
2331 if (t
.C_Constructor
== string.Empty
|| t
.C_Constructor
== null || !t
.GenerateCBindingCtor
) {
2332 //Console.WriteLine ("{0} does not have a C ctor", t.FullName);
2333 if (t
.GetTotalEventCount () == 0)
2337 if (string.IsNullOrEmpty (t
.Header
)) {
2338 // Console.WriteLine ("{0} does not have a header", t.FullName);
2342 //Console.WriteLine ("{0}'s header is {1}", t.FullName, t.Header);
2344 header
= Path
.GetFileName (t
.Header
);
2345 if (!headers
.Contains (header
))
2346 headers
.Add (header
);
2349 // Loop through all the classes and check which headers
2350 // are needed for the c constructors
2351 text
.AppendLine ("");
2353 foreach (string h
in headers
) {
2354 text
.Append ("#include \"");
2356 text
.AppendLine ("\"");
2360 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
2361 if (t
.GetEventCount () == 0)
2365 foreach (FieldInfo field
in t
.Events
) {
2366 text
.Append ("const int ");
2367 text
.Append (t
.Name
);
2369 text
.Append (field
.EventName
);
2370 text
.Append ("Event = ");
2371 text
.Append (t
.GetEventId (field
));
2372 text
.AppendLine (";");
2376 // Create the arrays of event names for the classes which have events
2377 text
.AppendLine ("");
2378 foreach (TypeInfo t
in all
.Children
.SortedTypesByKind
) {
2380 if (t
.Events
.Count
> 0) {
2381 text
.Append ("const char *");
2382 text
.Append (t
.KindName
);
2383 text
.Append ("_Events [] = { ");
2385 foreach (FieldInfo field
in t
.Events
) {
2387 text
.Append (field
.EventName
);
2388 text
.Append ("\", ");
2391 text
.AppendLine ("NULL };");
2394 if (t
.Interfaces
.Count
> 0) {
2395 text
.Append ("const Type::Kind ");
2396 text
.Append (t
.KindName
);
2397 text
.Append ("_Interfaces[] = { ");
2399 for (int i
= 0; i
< t
.Interfaces
.Count
; i
++) {
2400 text
.Append ("Type::");
2401 text
.Append (t
.Interfaces
[i
].KindName
);
2402 if (i
< t
.Interfaces
.Count
- 1)
2406 text
.AppendLine (" };");
2410 // Create the array of type data
2411 text
.AppendLine ("");
2412 text
.AppendLine ("void");
2413 text
.AppendLine ("Types::RegisterNativeTypes ()");
2414 text
.AppendLine ("{");
2415 text
.AppendLine ("\ttypes [(int) Type::INVALID] = new Type (Type::INVALID, Type::INVALID, false, false, NULL, 0, 0, NULL, 0, NULL, false, NULL, NULL );");
2416 foreach (TypeInfo type
in all
.Children
.SortedTypesByKind
) {
2418 TypeInfo parent
= null;
2419 string events
= "NULL";
2420 string interfaces
= "NULL";
2422 if (!type
.Annotations
.ContainsKey ("IncludeInKinds"))
2425 if (type
.Base
!= null && type
.Base
.Value
!= null && all
.Children
.TryGetValue (type
.Base
.Value
, out member
))
2426 parent
= (TypeInfo
) member
;
2428 if (type
.Events
!= null && type
.Events
.Count
!= 0)
2429 events
= type
.KindName
+ "_Events";
2431 if (type
.Interfaces
.Count
!= 0)
2432 interfaces
= type
.KindName
+ "_Interfaces";
2434 text
.AppendLine (string.Format (@" types [(int) {0}] = new Type ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12});",
2435 "Type::" + type
.KindName
,
2436 type
.KindName
== "OBJECT" ? "Type::INVALID" : ("Type::" + (parent
!= null ? parent
.KindName
: "OBJECT")),
2437 type
.IsValueType
? "true" : "false",
2438 type
.IsInterface
? "true" : "false",
2439 "\"" + type
.Name
+ "\"",
2440 type
.GetEventCount (),
2441 type
.GetTotalEventCount (),
2443 type
.Interfaces
.Count
,
2445 type
.DefaultCtorVisible
? "true" : "false",
2446 (type
.C_Constructor
!= null && type
.GenerateCBindingCtor
) ? string.Concat ("(create_inst_func *) ", type
.C_Constructor
) : "NULL",
2447 type
.ContentProperty
!= null ? string.Concat ("\"", type
.ContentProperty
, "\"") : "NULL"
2452 text
.AppendLine ("\ttypes [(int) Type::LASTTYPE] = new Type (Type::LASTTYPE, Type::INVALID, false, false, NULL, 0, 0, NULL, 0, NULL, false, NULL, NULL);");
2454 text
.AppendLine ("}");
2458 Helper
.WriteAllText ("src/type-generated.cpp", text
.ToString ());
2461 static void GenerateTypeH (GlobalInfo all
)
2463 const string file
= "src/type.h";
2465 string contents
= File
.ReadAllText (file
+ ".in");
2467 contents
= contents
.Replace ("/*DO_KINDS*/", all
.Children
.GetKindsForEnum ().ToString ());
2469 text
= new StringBuilder ();
2471 Helper
.WriteWarningGenerated (text
);
2473 contents
= text
.ToString () + contents
;
2475 Helper
.WriteAllText (file
, contents
);
2478 static void GenerateKindCs ()
2480 const string file
= "src/type.h";
2481 StringBuilder text
= new StringBuilder ();
2482 string contents
= File
.ReadAllText (file
);
2483 int a
= contents
.IndexOf ("// START_MANAGED_MAPPING") + "// START_MANAGED_MAPPING".Length
;
2484 int b
= contents
.IndexOf ("// END_MANAGED_MAPPING");
2485 string values
= contents
.Substring (a
, b
- a
);
2487 Helper
.WriteWarningGenerated (text
);
2489 text
.AppendLine ("namespace Mono {");
2490 text
.AppendLine ("#if NET_2_1");
2491 text
.AppendLine ("\tinternal enum Kind {");
2492 text
.AppendLine ("#else");
2493 text
.AppendLine ("\tpublic enum Kind {");
2494 text
.AppendLine ("#endif");
2495 text
.AppendLine (values
);
2496 text
.AppendLine ("\t}");
2497 text
.AppendLine ("}");
2499 string realfile
= "class/System.Windows/Mono/Kind.cs".Replace ('/', Path
.DirectorySeparatorChar
);
2500 Helper
.WriteAllText (realfile
, text
.ToString ());
2503 static void GenerateValueH (GlobalInfo all
)
2505 const string file
= "src/value.h";
2506 StringBuilder result
= new StringBuilder ();
2508 Helper
.WriteWarningGenerated (result
);
2510 using (StreamReader reader
= new StreamReader (file
+ ".in")) {
2512 line
= reader
.ReadLine ();
2513 while (line
!= null) {
2514 if (line
.Contains ("/*DO_FWD_DECLS*/")) {
2515 foreach (TypeInfo type
in all
.Children
.SortedTypesByKind
) {
2516 if (!type
.Annotations
.ContainsKey("IncludeInKinds") ||
2517 type
.Annotations
.ContainsKey("SkipValue") ||
2522 if (type
.IsStruct
) {
2523 forward_decls
.Append ("struct ");
2525 forward_decls
.Append ("class ");
2527 forward_decls
.Append (type
.Name
);
2528 forward_decls
.AppendLine (";");
2530 forward_decls
.AppendLine ();
2531 result
.Append (forward_decls
.ToString ());
2532 } else if (line
.Contains ("/*DO_AS*/")) {
2533 foreach (TypeInfo type
in all
.Children
.SortedTypesByKind
) {
2534 if (!type
.Annotations
.ContainsKey("IncludeInKinds") ||
2535 type
.Annotations
.ContainsKey("SkipValue") ||
2540 //do_as.AppendLine (string.Format (" {1,-30} As{0} () {{ checked_get_subclass (Type::{2}, {0}) }}", type.Name, type.Name + "*", type.KindName));
2542 result
.Append ('\t');
2543 result
.Append (type
.Name
);
2544 result
.Append ("*");
2545 result
.Append (' ', 40 - type
.Name
.Length
);
2546 result
.Append ("As");
2547 result
.Append (type
.Name
);
2548 result
.Append (" (Types *types = NULL) { checked_get_subclass (Type::");
2549 result
.Append (type
.KindName
);
2550 result
.Append (", ");
2551 result
.Append (type
.Name
);
2552 result
.Append (") }");
2553 result
.AppendLine ();
2555 result
.AppendLine ();
2557 result
.AppendLine (line
);
2559 line
= reader
.ReadLine ();
2563 Helper
.WriteAllText (file
, result
.ToString ());
2567 static bool IsManuallyDefined (string NativeMethods_cs
, string method
)
2569 if (NativeMethods_cs
.Contains (" " + method
+ " "))
2571 else if (NativeMethods_cs
.Contains (" " + method
+ "("))
2573 else if (NativeMethods_cs
.Contains ("\"" + method
+ "\""))
2580 static void GeneratePInvokes (GlobalInfo all
)
2582 string base_dir
= Environment
.CurrentDirectory
;
2583 List
<MethodInfo
> methods
= new List
<MethodInfo
> ();
2584 StringBuilder text
= new StringBuilder ();
2585 string NativeMethods_cs
;
2587 NativeMethods_cs
= File
.ReadAllText (Path
.Combine (base_dir
, "class/System.Windows/Mono/NativeMethods.cs".Replace ('/', Path
.DirectorySeparatorChar
)));
2589 methods
= all
.CPPMethodsToBind
;
2591 foreach (MemberInfo info
in all
.Children
.Values
) {
2592 MethodInfo minfo
= info
as MethodInfo
;
2595 if (!minfo
.Annotations
.ContainsKey ("GeneratePInvoke"))
2597 foreach (MethodInfo mi
in methods
) {
2598 if (mi
.CMethod
.Name
== minfo
.Name
) {
2605 //Console.WriteLine ("Added: {0} IsSrc: {1} IsPlugin: {2} Header: {3}", minfo.Name, minfo.IsSrcMember, minfo.IsPluginMember, minfo.Header);
2606 methods
.Add (minfo
);
2609 Helper
.WriteWarningGenerated (text
);
2610 text
.AppendLine ("using System;");
2611 text
.AppendLine ("using System.Windows;");
2612 text
.AppendLine ("using System.Runtime.InteropServices;");
2613 text
.AppendLine ("");
2614 text
.AppendLine ("namespace Mono {");
2615 text
.AppendLine ("\tinternal static partial class NativeMethods");
2616 text
.AppendLine ("\t{");
2617 text
.AppendLine ("\t\t/* moonplugin methods */");
2618 text
.AppendLine ("\t");
2619 foreach (MethodInfo method
in methods
) {
2620 if (!method
.IsPluginMember
|| !method
.Annotations
.ContainsKey ("GeneratePInvoke"))
2622 WritePInvokeMethod (NativeMethods_cs
, method
, text
, "moonplugin");
2626 text
.AppendLine ("\t");
2627 text
.AppendLine ("\t\t/* libmoon methods */");
2628 text
.AppendLine ("\t");
2629 foreach (MethodInfo method
in methods
) {
2630 if (!method
.IsSrcMember
|| !method
.Annotations
.ContainsKey ("GeneratePInvoke"))
2632 WritePInvokeMethod (NativeMethods_cs
, method
, text
, "moon");
2635 text
.AppendLine ("\t}");
2636 text
.AppendLine ("}");
2638 Helper
.WriteAllText (Path
.Combine (base_dir
, "class/System.Windows/Mono/GeneratedPInvokes.cs".Replace ('/', Path
.DirectorySeparatorChar
)), text
.ToString ());
2641 static void WritePInvokeMethod (string NativeMethods_cs
, MethodInfo method
, StringBuilder text
, string library
)
2643 bool marshal_string_returntype
= false;
2644 bool marshal_moonerror
= false;
2645 bool generate_wrapper
= false;
2646 // bool is_manually_defined;
2648 bool is_void
= false;
2649 bool contains_unknown_types
;
2651 string managed_name
;
2653 TypeReference returntype
;
2654 MethodInfo cmethod
= method
.CMethod
;
2655 ParameterInfo error_parameter
= null;
2657 if (method
.ReturnType
== null)
2658 throw new Exception (string.Format ("Method {0} in type {1} does not have a return type.", method
.Name
, method
.Parent
.Name
));
2660 if (method
.ReturnType
.Value
== "char*") {
2661 marshal_string_returntype
= true;
2662 generate_wrapper
= true;
2663 } else if (method
.ReturnType
.Value
== "void") {
2667 // Check for parameters we can automatically generate code for.
2668 foreach (ParameterInfo parameter
in cmethod
.Parameters
) {
2669 if (parameter
.Name
== "error" && parameter
.ParameterType
.Value
== "MoonError*") {
2670 marshal_moonerror
= true;
2671 generate_wrapper
= true;
2672 error_parameter
= parameter
;
2676 name
= method
.CMethod
.Name
;
2677 managed_name
= name
;
2678 if (marshal_moonerror
)
2679 managed_name
= managed_name
.Replace ("_with_error", "");
2681 returntype
= method
.ReturnType
;
2682 // is_manually_defined = IsManuallyDefined (NativeMethods_cs, managed_name);
2683 contains_unknown_types
= method
.ContainsUnknownTypes
;
2684 comment_out
= contains_unknown_types
;
2685 tabs
= comment_out
? "\t\t// " : "\t\t";
2687 // if (is_manually_defined)
2688 // text.AppendLine ("\t\t// NOTE: There is a method in NativeMethod.cs with the same name.");
2690 if (contains_unknown_types
)
2691 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.");
2694 text
.Append ("[DllImport (\"");
2695 text
.Append (library
);
2696 if (generate_wrapper
) {
2697 text
.Append ("\", EntryPoint=\"");
2700 text
.AppendLine ("\")]");
2702 if (method
.ReturnType
.Value
== "bool") {
2704 text
.AppendLine ("[return: MarshalAs (UnmanagedType.U1)]");
2705 } else if (method
.ReturnType
.Value
== "gboolean") {
2707 text
.AppendLine ("[return: MarshalAs (UnmanagedType.Bool)]");
2710 // Always output the native signature too, makes it easier to check if the generation is wrong.
2711 text
.Append ("\t\t// ");
2712 cmethod
.WriteFormatted (text
);
2716 text
.Append (generate_wrapper
? "private " : "public ");
2717 text
.Append ("extern static ");
2718 if (marshal_string_returntype
)
2719 text
.Append ("IntPtr");
2721 returntype
.Write (text
, SignatureType
.PInvoke
, null);
2724 if (generate_wrapper
)
2726 cmethod
.Parameters
.Write (text
, SignatureType
.PInvoke
, false);
2727 text
.AppendLine (";");
2729 if (generate_wrapper
) {
2731 text
.Append ("public static ");
2732 returntype
.Write (text
, SignatureType
.Managed
, null);
2734 text
.Append (managed_name
);
2736 foreach (ParameterInfo parameter
in cmethod
.Parameters
)
2737 parameter
.DisableWriteOnce
= parameter
.ManagedWrapperCode
!= null;
2739 if (error_parameter
!= null)
2740 error_parameter
.DisableWriteOnce
= true;
2742 cmethod
.Parameters
.Write (text
, SignatureType
.Managed
, false);
2751 if (marshal_string_returntype
) {
2752 text
.AppendLine ("\tIntPtr result;");
2753 } else if (!is_void
) {
2755 returntype
.Write (text
, SignatureType
.Managed
, null);
2756 text
.AppendLine (" result;");
2759 if (marshal_moonerror
) {
2761 text
.AppendLine ("\tMoonError error;");
2767 text
.Append ("result = ");
2769 text
.Append (cmethod
.Name
);
2771 cmethod
.Parameters
.Write (text
, SignatureType
.Managed
, true);
2773 text
.AppendLine (";");
2775 if (marshal_moonerror
) {
2777 text
.AppendLine ("\tif (error.Number != 0)");
2780 text
.AppendLine ("\t\tthrow CreateManagedException (error);");
2783 if (marshal_string_returntype
) {
2785 text
.AppendLine ("\tif (result == IntPtr.Zero)");
2787 text
.AppendLine ("\t\treturn null;");
2789 text
.AppendLine ("\tstring s = Marshal.PtrToStringAnsi (result);\t// *copy* unmanaged string");
2791 if (!method
.ReturnType
.IsConst
) {
2792 text
.AppendLine ("\tMarshal.FreeHGlobal (result);\t\t\t// g_free the unmanaged string");
2795 text
.AppendLine ("\treturn s;");
2796 } else if (!is_void
) {
2798 text
.AppendLine ("\treturn result;");
2808 static void RemoveExcludedSrcFiles (string srcdir
, List
<string> files
)
2810 files
.Remove (Path
.Combine (srcdir
, "cbinding.h"));
2811 files
.Remove (Path
.Combine (srcdir
, "ptr.h"));