Introspect/NameSpace.js
[gnome.introspection-doc-generator] / Introspect / NameSpace.js
1 //<script type="text/javascript">
2 //Gtk = imports.gi.Gtk;
3 GI      = imports.gi.GIRepository;
4 GLib    = imports.gi.GLib;
5 xml     = imports.libxml;
6 File    = imports.File.File;
7
8 XObject = imports.XObject.XObject;
9
10 console = imports.console.console;
11
12 // BC/FC
13 if (!GI.Repository) {
14     GI.Repository = GI.IRepository;
15     
16     GI.InfoType = GI.IInfoType;
17     
18     GI.IBaseInfo.prototype.get_name = function(n) {
19         return GI.base_info_get_name(this, n);
20     }
21      GI.IBaseInfo.prototype.get_namespace = function(n) {
22         return GI.base_info_get_namespace(this, n);
23     }
24     
25 }
26
27
28
29 NameSpace = {
30    
31     references : { }, 
32     
33     namespaces : function(ns) 
34     {
35         // this should be a class of it's own...
36         this.references[ns] = []; // technically not needed - but fills in files..
37         // get this from GI... (it's the path..)
38         var ret = [];
39        
40         function scanGir(dir) 
41         {
42             if (!GLib.file_test(dir, GLib.FileTest.EXISTS)) {
43                 return;
44             }
45             File.list(dir).forEach(function(fn) 
46             {
47                 if (!fn.match(/\.typelib$/)) {
48                     return;
49                 }
50                 var par = fn.split('-').shift();
51                  //console.log('trying ' +  par);
52                 if (ret.indexOf(par) > -1) {
53                      return;
54                 }
55                 ret.push(par);
56             }); 
57         }
58         
59         var gi = GI.Repository.get_default();
60         var pth = GI.Repository.get_search_path();
61         
62         scanGir(pth[0]);
63         ret.sort();
64         console.dump(ret);
65         return ret;
66         
67     },
68         
69         
70     ns:  function(ns) {
71         var gi = GI.Repository.get_default();
72         ret = {
73             titleType: 'Namespace',
74             ns: ns,
75             name : ns,
76             alias : ns,
77             objects : [],
78             functions : [],
79             enums : [],
80             structs: [],
81             constants : [],
82             unions : [],
83             
84             // so ns looks like class..
85           
86             extendsClasses : [], // what it extends...
87             childClasses : [], // what uses it..
88             properties : [],
89             constructors : [],
90             methods : [],
91             values : [], /// really constants.
92             signals : [],
93             interfaces: [],
94         };
95      
96         for (var i=0; i <  gi.get_n_infos (ns); i++ ) {
97             var info = gi.get_info (ns, i);
98            // print("NAME: " + info.get_name());
99             //continue;
100             var info_type = GI.base_info_get_type (info);
101            // print("Type: " + info_type);
102             switch(info_type) {
103                 case  GI.InfoType.OBJECT:
104                     ret.objects.push(info.get_name());
105                     this.clsGatherInterfaces(ns , info.get_name());
106                     continue;
107                  case  GI.InfoType.INTERFACE:
108                     ret.interfaces.push(info.get_name());
109                     continue;
110                 case  GI.InfoType.FUNCTION:
111                     new imports.Method.Method(info, ret, 'functions', []);    
112                     continue;
113                 
114                 case  GI.InfoType.CALLBACK:
115                    // new Introspect.Callback(info, ret, 'callbacks', []);
116                     continue;
117                 
118                 case  GI.InfoType.ENUM:
119                 case  GI.InfoType.FLAGS:
120                     ret.enums.push(info.get_name());
121                     continue;
122                 case  GI.InfoType.STRUCT:
123                     if (GI.struct_info_is_gtype_struct (info)) {
124                         continue;
125                     }
126
127                     ret.structs.push(info.get_name());
128                     continue;
129                 case  GI.InfoType.UNION:
130                     ret.unions.push(info.get_name());
131                     continue;
132                 case  GI.InfoType.CONSTANT:
133                     new imports.Constant.Constant(info, ret, 'values', []);
134                     
135                     continue;
136                 
137                 
138                 default:
139                     continue;
140             }
141         }
142         print ("SCAN NAMESPACE ALL DONE");
143                 
144         var gi = GI.Repository.get_default();
145         var ver = gi.get_version(ns);
146         var pth = GI.Repository.get_search_path ();
147         var gir_path = pth[0].replace(/lib\/girepository-1.0/, 'share\/gir-1.0');
148        //console.log(fn);
149         ret.gir_file = gir_path + '/'+ ns + '-' + ver + '.gir';
150         ret.gir_filename = ns + '-' + ver + '.gir';
151         
152         //console.dump(this.ifaceList);
153         return ret;
154
155     },
156  
157     
158
159     // store all the interfaces, so we can show a list of them later...
160     // called when you list the namespace
161     clsGatherInterfaces : function(ns, cls)
162     {
163        // print("clsGatherInterfaces: " + ns + ", " + cls);
164         var gi = GI.Repository.get_default();
165         var bb = gi.find_by_name(ns, cls);
166         var fullname = ns+'.'+cls;
167         this.ifaceList = this.ifaceList || { };
168          
169         
170         for(var i =0; i < GI.object_info_get_n_interfaces(bb); i++) {
171            
172             var prop = GI.object_info_get_interface(bb,i);
173            
174             var add =  prop.get_namespace() +'.' + prop.get_name();
175             this.ifaceList[add] = this.ifaceList[add] || [];
176             if (this.ifaceList[add].indexOf(fullname) < 0) {
177                 this.ifaceList[add].push(fullname);
178             }
179              
180         }
181         
182        
183         
184     },
185     
186            
187         
188    
189     doc : function(what) {
190         print ("DOC: + " +what);
191         var ns = what.split('.').shift();
192         return '';
193         this.commentLoad(ns);
194         return typeof(this.comments[ns][what]) == 'undefined' ?  '' : this.comments[ns][what];
195         
196     },
197     
198     
199     
200     comments : {},
201     
202     commentLoad : function(ns)
203     {
204         
205         if (typeof(this.comments[ns]) != 'undefined') {
206             return;
207         }
208         
209         console.log("LOAD DOCS: " + ns);
210         var gi = GI.Repository.get_default();
211         var ver = gi.get_version(ns);
212         if (!ver) {
213             this.comments[ns] = {};
214             return;
215         }
216         var ret = { };
217         
218         // no idea why this is broken on my build system.
219         var  getAttribute = function(n, name){
220             var properties = n.properties;
221             while (properties){
222                 if (properties.name == name)
223                     return properties.children.content;
224                 properties = properties.next
225             }
226             return null;
227         }
228                 
229         
230         function walk (element, path) {
231             
232             
233             if (!element) {
234                 return;
235             }
236             
237             var n =  getAttribute(element, 'name') ;
238             //console.log("WALK" + n);
239             if (element.name == 'signal') {
240                 path += '.signal';
241             }
242             
243             if (n) {
244                 path += path.length ? '.' : '';
245                 path += n;
246             }
247             if (element.name == 'return-value') {
248                 path += '.return-value';
249             }
250             
251             var d =   getAttribute(element,'doc');
252             if (d) {
253              //   Seed.print(path + ':' + d);
254                 ret[path] = d;
255             }
256             
257             var child = element.children;
258
259             while (child){
260                 //console.log(child.tag);
261                 if (child.type == "element"){
262                     walk (child, path);
263                 }
264                 child = child.next;
265             }
266         }
267         
268         var pth = GI.Repository.get_search_path ();
269         
270         
271         var gir_path = pth[0].replace(/lib\/girepository-1.0/, 'share\/gir-1.0');
272        
273         
274         //console.log(fn);
275         var  fn = gir_path + '/'+ ns + '-' + ver + '.gir';
276        // console.log(fn);
277         
278         if (!GLib.file_test(fn, GLib.FileTest.EXISTS)) {
279             console.log('missing docc file ' + fn);
280             this.comments[ns] = {};
281             
282             return;
283         }
284         var doc = xml.parseFile(fn);
285         //console.log("xmldoc?" + doc);
286         walk (doc.root, '');
287         //console.dump(ret);
288         this.comments[ns] = ret;
289
290     },
291     registry : { },
292     factory : function(type, ns, name) {
293         if (typeof (this.registry[ns +'.' + name]) == 'undefined') {
294             this.registry[ns +'.' + name] = new imports[type][type](ns,name);
295             this.registry[ns +'.' + name].load();
296         }
297         
298         return this.registry[ns +'.' + name];
299     }
300         
301 };
302
303
304