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