JSDOC/Symbol.js
[gnome.introspection-doc-generator] / JSDOC / Symbol.js
1 //<script type="text/javascript">
2
3 XObject         = imports.XObject.XObject;
4
5 SymbolSet       = imports.SymbolSet.SymbolSet;
6 //Parser          = imports.Parser.Parser;
7 DocComment      = imports.DocComment.DocComment;
8 DocTag          = imports.DocTag.DocTag;
9 /**
10         Create a new Symbol.
11         @class Represents a symbol in the source code.
12  */
13 Symbol = XObject.define(
14     function() {
15         this.init();
16         if (arguments.length) this.populate.apply(this, arguments);
17         
18     },
19     Object,
20     {
21         
22             
23         
24         toObject : function()
25         {
26             
27             function array2object(a , m)
28             {
29                 var r = [];
30                 a.forEach(function(e) {
31                     r.push(m ? e : e.toObject());
32                 }
33             }
34             var ret = { };
35             for (var i in this) {
36                 switch (typeof(this[i])) {
37                     case 'function':
38                         continue;
39                     case 'object':
40                     
41                         print("object? :" + i);
42                         Seed.quit();
43                     case 'string':
44                     case 'number':
45                         ret[i] = this[i]; continue;
46                     default:
47                         print("unknown type:" + typeof(this[i]));
48                         Seed.quit();
49                    }
50             }
51             
52             
53         },
54         
55         init : function() 
56         {
57             this.name = "";
58             this.defaultValue = "";
59             this.params = [];
60             this.$args = [];
61             this.addOn = "";
62             this.alias = "";
63             this.augments = [];
64             this.author = "";
65             this.classDesc = "";
66             this.comment = { isUserComment: false };
67             //this.defaultValue = null;
68             this.deprecated = "";
69             this.desc = "";
70             this.events = [];
71             this.example = "";
72             this.exceptions = [];
73             this.inherits = [];
74             this.inheritsFrom = [];
75             this.isa = "OBJECT"; // OBJECT//FUNCTION
76             this.isEvent = false;
77             this.isConstant = false;
78             this.isIgnored = false;
79             this.isInner = false;
80             this.isNamespace = false;
81             this.isPrivate = false;
82             this.isStatic = false;
83             this.memberOf = "";
84             this.methods = [];
85             this._name = "";
86             this._params = [];
87             this.properties = [];
88             this.requires = [];
89             this.returns = [];
90             this.see = [];
91             this.since = "";
92             this.srcFile = {};
93             this.type = "";
94             this.version = "";
95             this.childClasses = [];
96             this.cfgs = {};
97                
98         },
99
100         serialize : function() {
101             var keys = [];
102             for (var p in this) {
103                 keys.push (p);
104             }
105             keys = keys.sort();
106             
107             var out = "";
108             for (var i in keys) {
109                 if (typeof this[keys[i]] == "function") continue;
110                 out += "     " +keys[i]+" => "+
111                     (   
112                         (typeof(this[keys[i]]) != "object") ?  
113                             this[keys[i]] :
114                             "[" +typeof(this[keys[i]])+"]"
115                     ) + 
116                     ",\n";
117             }
118             return "\n{\n" + out + "}\n";
119         },
120
121         clone : function() {
122             var clone = new Symbol();
123             clone.populate.apply(clone, this.$args); // repopulate using the original arguments
124             clone.srcFile = this.srcFile; // not the current srcFile, the one when the original was made
125             return clone;
126         },
127
128
129
130
131         //__defineSetter__("name",
132         setName  : function(n) { 
133                 n = n.replace(/^_global_[.#-]/, ""); 
134                 n = n.replace(/\.prototype\.?/g, '#'); 
135                  n = n.replace(/#$/g, ''); 
136                 this._name = n;
137                 this.name = n; // real!
138             },
139         //);
140         //__defineGetter__("name",
141         getName : function() { return this._name; },
142         //);
143         //__defineSetter__("params", 
144         setParams  :function(v) {
145                 for (var i = 0, l = v.length; i < l; i++) {
146                     if (v[i].constructor != DocTag) { // may be a generic object parsed from signature, like {type:..., name:...}
147                         var ty = v[i].hasOwnProperty('type') ? v[i].type : '';
148                         this._params[i] = new DocTag(
149                             "param"+((ty)?" {"+ty+"}":"")+" "+v[i].name);
150                     }
151                     else {
152                         this._params[i] = v[i];
153                     }
154                 }
155                 this.params = this._params;
156             },
157         //);
158
159
160         //__defineGetter__("params",
161         getParams : function() { return this._params; },
162         //);
163
164         populate : function(
165                 /** String */ name,
166                 /** Object[] */ params,
167                 /** String */ isa,
168                 /** DocComment */ comment
169         ) {
170             this.$args = arguments;
171             //println("Symbol created: " + isa + ":" + name);
172             this.setName(name);
173             this.alias = this.getName();
174             this.setParams(params);
175             this.isa = (isa == "VIRTUAL")? "OBJECT":isa;
176             this.comment = comment || new DocComment("");
177             this.srcFile = Symbol.srcFile;
178             
179            
180             
181             if (this.is("FILE") && !this.alias) this.alias = this.srcFile;
182
183             this.setTags();
184             
185             //if (typeof PluginManager != "undefined") {
186             //    PluginManager.run("onSymbol", this);
187             //}
188         },
189
190         setTags : function() {
191             // @author
192             var authors = this.comment.getTag("author");
193             if (authors.length) {
194                 this.author = authors.map(function($){return $.desc;}).join(", ");
195             }
196             
197             /*~t
198                 assert("testing Symbol");
199                 
200                 requires("../lib/JSDOC/DocComment.js");
201                 requires("../frame/String.js");
202                 requires("../lib/JSDOC/DocTag.js");
203
204                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@author Joe Smith*"+"/"));
205                 assertEqual(sym.author, "Joe Smith", "@author tag, author is found.");
206             */
207             // @desc
208             var mth = this.comment.getTag("method");
209             if (mth.length) {
210                 this.isa = "FUNCTION";
211             }
212             // @desc
213             var descs = this.comment.getTag("desc");
214             if (descs.length) {
215                 this.desc = descs.map(function($){return $.desc;}).join("\n"); // multiple descriptions are concatenated into one
216             }
217             
218             /*~t
219                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@desc This is a description.*"+"/"));
220                 assertEqual(sym.desc, "This is a description.", "@desc tag, description is found.");
221             */
222             
223             // @overview
224             if (this.is("FILE")) {
225                 if (!this.alias) this.alias = this.srcFile;
226                 
227                 var overviews = this.comment.getTag("overview");
228                 if (overviews.length) {
229                     this.desc = [this.desc].concat(overviews.map(function($){return $.desc;})).join("\n");
230                 }
231             }
232             
233             /*~t
234                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@overview This is an overview.*"+"/"));
235                 assertEqual(sym.desc, "\nThis is an overview.", "@overview tag, description is found.");
236             */
237             
238             // @since
239             var sinces = this.comment.getTag("since");
240             if (sinces.length) {
241                 this.since = sinces.map(function($){return $.desc;}).join(", ");
242             }
243             
244             /*~t
245                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@since 1.01*"+"/"));
246                 assertEqual(sym.since, "1.01", "@since tag, description is found.");
247             */
248             
249             // @constant
250             if (this.comment.getTag("constant").length) {
251                 this.isConstant = true;
252                 this.isa = 'OBJECT';
253             }
254             
255             /*~t
256                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@constant*"+"/"));
257                 assertEqual(sym.isConstant, true, "@constant tag, isConstant set.");
258             */
259             
260             // @version
261             var versions = this.comment.getTag("version");
262             if (versions.length) {
263                 this.version = versions.map(function($){return $.desc;}).join(", ");
264             }
265             
266             /*~t
267                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@version 2.0x*"+"/"));
268                 assertEqual(sym.version, "2.0x", "@version tag, version is found.");
269             */
270             
271             // @deprecated
272             var deprecateds = this.comment.getTag("deprecated");
273             if (deprecateds.length) {
274                 this.deprecated = deprecateds.map(function($){return $.desc;}).join("\n");
275             }
276             
277             /*~t
278                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@deprecated Use other method.*"+"/"));
279                 assertEqual(sym.deprecated, "Use other method.", "@deprecated tag, desc is found.");
280             */
281             
282             // @example
283             var examples = this.comment.getTag("example");
284             if (examples.length) {
285                 this.example = examples[0];
286             }
287             
288             /*~t
289                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@example This\n  is an example.*"+"/"));
290                 assertEqual(sym.example, "This\n  is an example.", "@deprecated tag, desc is found.");
291             */
292             
293             // @see
294             var sees = this.comment.getTag("see");
295             if (sees.length) {
296                 var thisSee = this.see;
297                 sees.map(function($){thisSee.push($.desc);});
298             }
299             
300             /*~t
301                 var sym = new Symbol("foo", [], "FILE", new DocComment("/**@see The other thing.*"+"/"));
302                 assertEqual(sym.see, "The other thing.", "@see tag, desc is found.");
303             */
304             
305             // @class
306             var classes = this.comment.getTag("class");
307             if (classes.length) {
308                 this.isa = "CONSTRUCTOR";
309                 this.classDesc = classes[0].desc; // desc can't apply to the constructor as there is none.
310                 if (!this.classDesc) {
311                     this.classDesc = this.desc;
312                    }
313                 
314                 
315             }
316             
317             /*~t
318                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@class This describes the class.*"+"/"));
319                 assertEqual(sym.isa, "CONSTRUCTOR", "@class tag, makes symbol a constructor.");
320                 assertEqual(sym.classDesc, "This describes the class.", "@class tag, class description is found.");
321             */
322             
323             // @namespace
324             var namespaces = this.comment.getTag("namespace");
325             if (namespaces.length) {
326                 this.classDesc = namespaces[0].desc+"\n"+this.desc; // desc can't apply to the constructor as there is none.
327                 this.isNamespace = true;
328             }
329             
330             /*~t
331                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@namespace This describes the namespace.*"+"/"));
332                 assertEqual(sym.classDesc, "This describes the namespace.\n", "@namespace tag, class description is found.");
333             */
334             
335             // @param
336             var params = this.comment.getTag("param");
337             if (params.length) {
338                 // user-defined params overwrite those with same name defined by the parser
339                 var thisParams = this.getParams();
340
341                 if (thisParams.length == 0) { // none exist yet, so just bung all these user-defined params straight in
342                     this.setParams(params);
343                 }
344                 else { // need to overlay these user-defined params on to existing parser-defined params
345                     for (var i = 0, l = params.length; i < l; i++) {
346                         if (thisParams[i]) {
347                             if (params[i].type) thisParams[i].type = params[i].type;
348                             thisParams[i].name = params[i].name;
349                             thisParams[i].desc = params[i].desc;
350                             thisParams[i].isOptional = params[i].isOptional;
351                             thisParams[i].defaultValue = params[i].defaultValue;
352                         }
353                         else thisParams[i] = params[i];
354                     }
355                 }
356             }
357             
358             /*~t
359                 var sym = new Symbol("foo", [{type: "array", name: "pages"}], "FUNCTION", new DocComment("/**Description.*"+"/"));
360                 assertEqual(sym.params.length, 1, "parser defined param is found.");
361                 
362                 sym = new Symbol("foo", [], "FUNCTION", new DocComment("/**Description.\n@param {array} pages*"+"/"));
363                 assertEqual(sym.params.length, 1, "user defined param is found.");
364                 assertEqual(sym.params[0].type, "array", "user defined param type is found.");
365                 assertEqual(sym.params[0].name, "pages", "user defined param name is found.");
366                 
367                 sym = new Symbol("foo", [{type: "array", name: "pages"}], "FUNCTION", new DocComment("/**Description.\n@param {string} uid*"+"/"));
368                 assertEqual(sym.params.length, 1, "user defined param overwrites parser defined param.");
369                 assertEqual(sym.params[0].type, "string", "user defined param type overwrites parser defined param type.");
370                 assertEqual(sym.params[0].name, "uid", "user defined param name overwrites parser defined param name.");
371             
372                 sym = new Symbol("foo", [{type: "array", name: "pages"}, {type: "number", name: "count"}], "FUNCTION", new DocComment("/**Description.\n@param {string} uid*"+"/"));
373                 assertEqual(sym.params.length, 2, "user defined params  overlay parser defined params.");
374                 assertEqual(sym.params[1].type, "number", "user defined param type overlays parser defined param type.");
375                 assertEqual(sym.params[1].name, "count", "user defined param name overlays parser defined param name.");
376
377                 sym = new Symbol("foo", [], "FUNCTION", new DocComment("/**Description.\n@param {array} pages The pages description.*"+"/"));
378                 assertEqual(sym.params.length, 1, "user defined param with description is found.");
379                 assertEqual(sym.params[0].desc, "The pages description.", "user defined param description is found.");
380             */
381             
382             // @constructor
383             if (this.comment.getTag("constructor").length) {
384                 this.isa = "CONSTRUCTOR";
385             }
386             
387             /*~t
388                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@constructor*"+"/"));
389                 assertEqual(sym.isa, "CONSTRUCTOR", "@constructor tag, makes symbol a constructor.");
390             */
391             
392             // @static
393             if (this.comment.getTag("static").length) {
394                 this.isStatic = true;
395                 if (this.isa == "CONSTRUCTOR") {
396                     this.isNamespace = true;
397                 }
398             }
399             
400                 // @static
401             if (this.comment.getTag("singleton").length) {
402                 this.isStatic = true;
403                 //if (this.isa == "CONSTRUCTOR") {
404                 //      this.isNamespace = true;
405                 //}
406             }
407             
408             
409             
410             /*~t
411                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@static\n@constructor*"+"/"));
412                 assertEqual(sym.isStatic, true, "@static tag, makes isStatic true.");
413                 assertEqual(sym.isNamespace, true, "@static and @constructor tag, makes isNamespace true.");
414             */
415             
416             // @inner
417             if (this.comment.getTag("inner").length) {
418                 this.isInner = true;
419                 this.isStatic = false;
420             }
421             
422             /*~t
423                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@inner*"+"/"));
424                 assertEqual(sym.isStatic, false, "@inner tag, makes isStatic false.");
425                 assertEqual(sym.isInner, true, "@inner makes isInner true.");
426             */
427             
428             // @field
429             if (this.comment.getTag("field").length) {
430                 this.isa = "OBJECT";
431             }
432             
433             /*~t
434                 var sym = new Symbol("foo", [], "FUNCTION", new DocComment("/**@field*"+"/"));
435                 assertEqual(sym.isa, "OBJECT", "@field tag, makes symbol an object.");
436             */
437             
438             // @function
439             if (this.comment.getTag("function").length) {
440                 this.isa = "FUNCTION";
441             }
442             
443             // @param
444             if (this.comment.getTag("param").length && this.isa == "OBJECT" ) {
445                 // change a property to a function..
446                 this.isa = "FUNCTION";
447             }
448             
449             
450             /*~t
451                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@function*"+"/"));
452                 assertEqual(sym.isa, "FUNCTION", "@function tag, makes symbol a function.");
453             */
454             
455             // @event
456             var events = this.comment.getTag("event");
457             if (events.length) {
458                 this.isa = "FUNCTION";
459                 this.isEvent = true;
460             }
461             
462             /*~t
463                 var sym = new Symbol("foo", [], "OBJECT", new DocComment("/**@event*"+"/"));
464                 assertEqual(sym.isa, "FUNCTION", "@event tag, makes symbol a function.");
465                 assertEqual(sym.isEvent, true, "@event makes isEvent true.");
466             */
467             
468             // @name
469             var names = this.comment.getTag("name");
470             if (names.length) {
471                 this.setName(names[0].desc);
472             }
473             
474             /*~t
475                 // todo
476             */
477             
478             // @property
479             var properties = this.comment.getTag("property");
480             if (properties.length) {
481                 thisProperties = this.properties;
482                 for (var i = 0; i < properties.length; i++) {
483                     var property = new Symbol(this.alias+"#"+properties[i].name, [], "OBJECT", new DocComment("/**"+properties[i].desc+"\n@name "+properties[i].name+"\n@memberOf "+this.alias+"#*/"));
484                     // TODO: shouldn't the following happen in the addProperty method of Symbol?
485                     property.name = properties[i].name;
486                     property.memberOf = this.alias;
487                     if (properties[i].type) property.type = properties[i].type;
488                     if (properties[i].defaultValue) property.defaultValue = properties[i].defaultValue;
489                     this.addProperty(property);
490                     imports.Parser.Parser.addSymbol(property);
491                 }
492             }
493             
494             // config..
495             var conf = this.comment.getTag("cfg");
496             if (conf.length) {
497                 for (var i = 0; i < conf.length; i++) {
498                     this.addConfig(conf[i]);
499                 }
500             }
501             
502             /*~t
503                 // todo
504             */
505
506             // @return
507             var returns = this.comment.getTag("return");
508             if (returns.length) { // there can be many return tags in a single doclet
509                 this.returns = returns;
510                 this.type = returns.map(function($){return $.type}).join(", ");
511             }
512             
513             /*~t
514                 // todo
515             */
516             
517             // @exception
518             this.exceptions = this.comment.getTag("throws");
519             
520             /*~t
521                 // todo
522             */
523             
524             // @requires
525             var requires = this.comment.getTag("requires");
526             if (requires.length) {
527                 this.requires = requires.map(function($){return $.desc});
528             }
529             
530             /*~t
531                 // todo
532             */
533             
534             // @type
535             var types = this.comment.getTag("type");
536             if (types.length) {
537                 this.type = types[0].desc; //multiple type tags are ignored
538             }
539             
540             /*~t
541                 // todo
542             */
543             
544             // @private
545             if (this.comment.getTag("private").length || this.isInner) {
546                 this.isPrivate = true;
547             }
548             
549             // @ignore
550             if (this.comment.getTag("ignore").length) {
551                 this.isIgnored = true;
552             }
553             
554             /*~t
555                 // todo
556             */
557             
558             // @inherits ... as ...
559             var inherits = this.comment.getTag("inherits");
560             if (inherits.length) {
561                 for (var i = 0; i < inherits.length; i++) {
562                     if (/^\s*([a-z$0-9_.#-]+)(?:\s+as\s+([a-z$0-9_.#]+))?/i.test(inherits[i].desc)) {
563                         var inAlias = RegExp.$1;
564                         var inAs = RegExp.$2 || inAlias;
565
566                         if (inAlias) inAlias = inAlias.replace(/\.prototype\.?/g, "#");
567                         
568                         if (inAs) {
569                             inAs = inAs.replace(/\.prototype\.?/g, "#");
570                             inAs = inAs.replace(/^this\.?/, "#");
571                         }
572
573                         if (inAs.indexOf(inAlias) != 0) { //not a full namepath
574                             var joiner = ".";
575                             if (this.alias.charAt(this.alias.length-1) == "#" || inAs.charAt(0) == "#") {
576                                 joiner = "";
577                             }
578                             inAs = this.alias + joiner + inAs;
579                         }
580                     }
581                     this.inherits.push({alias: inAlias, as: inAs});
582                 }
583             }
584             
585             /*~t
586                 // todo
587             */
588
589             // @augments
590             this.augments = this.comment.getTag("augments");
591             
592             //@extends - Ext
593             if (this.comment.getTag("extends")) {   
594                 this.augments = this.comment.getTag("extends");
595             }
596             
597             
598             // @default
599             var defaults = this.comment.getTag("default");
600             if (defaults.length) {
601                 if (this.is("OBJECT")) {
602                     this.defaultValue = defaults[0].desc;
603                 }
604             }
605             
606             /*~t
607                 // todo
608             */
609             
610             // @memberOf
611             var memberOfs = this.comment.getTag("memberOf");
612             if (memberOfs.length) {
613                 this.memberOf = memberOfs[0].desc;
614                 this.memberOf = this.memberOf.replace(/\.prototype\.?/g, "#");
615             }
616
617             /*~t
618                 // todo
619             */
620             
621             // @public
622             if (this.comment.getTag("public").length) {
623                 this.isPrivate = false;
624             }
625             
626             /*~t
627                 // todo
628             */
629         },
630
631         is : function(what) {
632             return this.isa === what;
633         },
634
635         isBuiltin : function() {
636             return SymbolSet.isBuiltin(this.alias);
637         },
638
639         setType : function(/**String*/comment, /**Boolean*/overwrite) {
640             if (!overwrite && this.type) return;
641             var typeComment = DocComment.unwrapComment(comment);
642             this.type = typeComment;
643         },
644
645         inherit : function(symbol) {
646             if (!this.hasMember(symbol.name) && !symbol.isInner) {
647                 if (symbol.is("FUNCTION"))
648                     this.methods.push(symbol);
649                 else if (symbol.is("OBJECT"))
650                     this.properties.push(symbol);
651             }
652         },
653
654         hasMember : function(name) {
655             return (this.hasMethod(name) || this.hasProperty(name));
656         },
657
658         addMember : function(symbol) {
659             //println("ADDMEMBER: " + this.name +  " ++ " + symbol.name);
660             
661             if (symbol.comment.getTag("cfg").length == 1) { 
662                 symbol.comment.getTag("cfg")[0].memberOf = this.alias;
663                 this.addConfig(symbol.comment.getTag("cfg")[0]);
664                 return;
665             }
666             
667             if (symbol.is("FUNCTION")) { this.addMethod(symbol); }
668             else if (symbol.is("OBJECT")) { this.addProperty(symbol); }
669         },
670
671         hasMethod : function(name) {
672             var thisMethods = this.methods;
673             for (var i = 0, l = thisMethods.length; i < l; i++) {
674                 if (thisMethods[i].name == name) return true;
675                 if (thisMethods[i].alias == name) return true;
676             }
677             return false;
678         },
679
680         addMethod : function(symbol) {
681             var methodAlias = symbol.alias;
682             var thisMethods = this.methods;
683             for (var i = 0, l = thisMethods.length; i < l; i++) {
684                 if (thisMethods[i].alias == methodAlias) {
685                     thisMethods[i] = symbol; // overwriting previous method
686                     return;
687                 }
688             }
689             thisMethods.push(symbol); // new method with this alias
690         },
691
692         hasProperty : function(name) {
693             var thisProperties = this.properties;
694             for (var i = 0, l = thisProperties.length; i < l; i++) {
695                 if (thisProperties[i].name == name) return true;
696                 if (thisProperties[i].alias == name) return true;
697             }
698             return false;
699         },
700
701         addProperty : function(symbol) {
702             var propertyAlias = symbol.alias;
703             var thisProperties = this.properties;
704             for (var i = 0, l = thisProperties.length; i < l; i++) {
705                 if (thisProperties[i].alias == propertyAlias) {
706                     thisProperties[i] = symbol; // overwriting previous property
707                     return;
708                 }
709             }
710
711             thisProperties.push(symbol); // new property with this alias
712         },
713         
714         addDocTag : function(docTag)
715         {
716             this.comment.tags.push(docTag);
717             if (docTag.title == 'cfg') {
718                 this.addConfig(docTag);
719             }
720             
721         },
722         
723         addConfig : function(docTag)
724         {
725             if (typeof(docTag['memberOf']) == 'undefined') {
726                 // remove prototype data...
727                 //var a = this.alias.split('#')[0];
728                 //docTag.memberOf = a;
729                 docTag.memberOf = this.alias;
730             }
731             if (typeof(this.cfgs[docTag.name]) == 'undefined') {
732                 this.cfgs[docTag.name] = docTag;
733             }
734             
735         },
736         configToArray: function()
737         {
738             var r = [];
739             for(var ci in this.cfgs) {
740                 // dont show hidden!!
741                 if (this.cfgs[ci].desc.match(/@hide/)) {
742                     continue;
743                 }
744                 r.push(this.cfgs[ci]); 
745                
746             }
747             return r;
748         }
749 });
750
751
752
753
754
755 Symbol.srcFile = ""; //running reference to the current file being parsed
756
757
758 Symbol.fromDump = function(t)
759 {
760     var ns = new Symbol();
761     for (var i in t) {
762         if (typeof(ns[i]) == "undefined") {
763             println("ERR:no default for Symbol:"+ i);
764         }
765         ns[i] = t[i];
766     }
767     return ns;
768 }