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