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