Sync API with GLib GDir head
[gnome.introspection-doc-generator] / JSDOC / Introspect.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
7
8 imports['Object.js'].load(Object);
9
10 console = imports['console.js'].console;
11
12
13 xnew    = imports['xnew.js'].xnew;
14
15  
16
17
18 Introspect = {};
19
20 xnew.load(Introspect,'JSDOC/Introspect');
21
22
23
24 Object.extend(Introspect, {
25     
26    
27     references : { }, 
28     
29     namespaces : function(ns) 
30     {
31         // this should be a class of it's own...
32         this.references[ns] = []; // technically not needed - but fills in files..
33         // get this from GI... (it's the path..)
34         var ret = [];
35        
36         function scanGir(dir) 
37         {
38             if (!GLib.file_test(dir, GLib.FileTest.EXISTS)) {
39                 return;
40             }
41             var gdir = GLib.dir_open(dir,0);
42             
43             while (true) {
44                 
45                 var fn = GLib.dir_read_name(gdir);
46            //      console.log('trying ' +  fn);
47                 if (!fn) {
48                     GLib.dir_close(gdir);
49                     return;;
50                 }
51                 if (!fn.match(/.typelib$/)) {
52                     continue;
53                 }
54                 var par = fn.split('-').shift();
55                  //console.log('trying ' +  par);
56                 if (ret.indexOf(par) > -1) {
57                      continue;
58                 }
59                 ret.push(par);
60                 
61                 
62             } 
63         }
64         var gi = GI.IRepository.get_default();
65         var pth = GI.IRepository.get_search_path ();
66         
67         scanGir(pth[0]);
68         ret.sort();
69         console.dump(ret);
70         return ret;
71         
72     },
73         
74         
75     ns:  function(ns) {
76         var gi = GI.IRepository.get_default();
77         ret = {
78             titleType: 'Namespace',
79             ns: ns,
80             name : ns,
81             alias : ns,
82             objects : [],
83             functions : [],
84             enums : [],
85             structs: [],
86             constants : [],
87             unions : [],
88             
89             // so ns looks like class..
90           
91             extendsClasses : [], // what it extends...
92             childClasses : [], // what uses it..
93             properties : [],
94             constructors : [],
95             methods : [],
96             values : [], /// really constants.
97             signals : [],
98             interfaces: [],
99         };
100      
101         for (var i=0; i <  gi.get_n_infos (ns); i++ ) {
102             var info = gi.get_info (ns, i);
103             
104             var info_type = GI.base_info_get_type (info);
105             switch(info_type) {
106                 case  GI.IInfoType.OBJECT:
107                     ret.objects.push(GI.base_info_get_name(info));
108                     this.clsGatherInterfaces(ns , GI.base_info_get_name(info));
109                     continue;
110                  case  GI.IInfoType.INTERFACE:
111                     ret.interfaces.push(GI.base_info_get_name(info));
112                     continue;
113                 case  GI.IInfoType.FUNCTION:
114                     new Introspect.Method(info, ret, 'functions', []);    
115                     continue;
116                 
117                 case  GI.IInfoType.CALLBACK:
118                    // new Introspect.Callback(info, ret, 'callbacks', []);
119                     continue;
120                 
121                 case  GI.IInfoType.ENUM:
122                 case  GI.IInfoType.FLAGS:
123                     ret.enums.push(GI.base_info_get_name(info));
124                     continue;
125                 case  GI.IInfoType.STRUCT:
126                     if (GI.struct_info_is_gtype_struct (info)) {
127                         continue;
128                     }
129
130                     ret.structs.push(GI.base_info_get_name(info));
131                     continue;
132                 case  GI.IInfoType.UNION:
133                     ret.unions.push(GI.base_info_get_name(info));
134                     continue;
135                 case  GI.IInfoType.CONSTANT:
136                     new Introspect.Constant(info, ret, 'values', []);
137                     
138                     continue;
139                 
140                 
141                 default:
142                     continue;
143             }
144         }
145         
146                 
147         var gi = GI.IRepository.get_default();
148         var ver = gi.get_version(ns);
149         var pth = GI.IRepository.get_search_path ();
150         var gir_path = pth[0].replace(/lib\/girepository-1.0/, 'share\/gir-1.0');
151        //console.log(fn);
152         ret.gir_file = gir_path + '/'+ ns + '-' + ver + '.gir';
153         ret.gir_filename = ns + '-' + ver + '.gir';
154         
155         //console.dump(this.ifaceList);
156         return ret;
157
158     },
159  
160     
161   
162     // store all the interfaces, so we can show a list of them later...
163     // called when you list the namespace
164     clsGatherInterfaces : function(ns, cls)
165     {
166         var gi = GI.IRepository.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 =  GI.base_info_get_namespace(prop) +'.' + GI.base_info_get_name(prop);
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         var ns = what.split('.').shift();
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.IRepository.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 (n) {
240                 path += path.length ? '.' : '';
241                 path += n;
242             }
243             if (element.name == 'return-value') {
244                 path += '.return-value';
245             }
246             
247             
248             var d =   getAttribute(element,'doc');
249             if (d) {
250              //   Seed.print(path + ':' + d);
251                 ret[path] = d;
252             }
253             
254             var child = element.children;
255
256             while (child){
257                 //console.log(child.tag);
258                 if (child.type == "element"){
259                     walk (child, path);
260                 }
261                 child = child.next;
262             }
263         }
264         
265         var pth = GI.IRepository.get_search_path ();
266         
267         
268         var gir_path = pth[0].replace(/lib\/girepository-1.0/, 'share\/gir-1.0');
269        
270         
271         //console.log(fn);
272         var  fn = gir_path + '/'+ ns + '-' + ver + '.gir';
273        // console.log(fn);
274         
275         if (!GLib.file_test(fn, GLib.FileTest.EXISTS)) {
276             console.log('missing docc file ' + fn);
277             this.comments[ns] = {};
278             
279             return;
280         }
281         var doc = xml.parseFile(fn);
282         //console.log("xmldoc?" + doc);
283         walk (doc.root, '');
284         //console.dump(ret);
285         this.comments[ns] = ret;
286
287     },
288     registry : { },
289     factory : function(type, ns, name) {
290         if (typeof (this.registry[ns +'.' + name]) == 'undefined') {
291             this.registry[ns +'.' + name] = new Introspect[type](ns,name);
292             this.registry[ns +'.' + name].load();
293         }
294         
295         return this.registry[ns +'.' + name];
296     }
297         
298             
299     
300 });
301
302
303