JSDOC/DocTag.js
[gnome.introspection-doc-generator] / JSDOC / DocTag.js
1 //<script  type="text/javascript">
2  
3  
4 XObject = imports.XObject.XObject;
5
6 DocTag = imports.DocTag.DocTag;
7 /**
8  * DocTag - represents a single A=b tag.
9  * @class DocTag
10  */
11  
12  
13 DocTag = XObject.define(
14     function(src) {
15         this.title        = "";
16         this.type         = "";
17         this.name         = "";
18         this.isOptional   = false;
19         this.defaultValue = "";
20         this.desc         = "";
21         if (typeof src != "undefined") {
22             this.parse(src);
23         }
24     }, 
25     Object,
26     {
27         
28         title: '',
29         type: '',
30         name : '',
31         isOptional : false,
32         defaultValue : '',
33         desc : '',
34         
35         toQDump  :function(t)
36         {
37             return JSDOC.toQDump(t, 'JSDOC.DocTag.fromDump({', '})', new JSDOC.DocTag());
38         } ,
39
40
41
42         /**
43             Populate the properties of this from the given tag src.
44             @param {string} src
45          */
46         parse : function(src) {
47             if (typeof src != "string") throw "src must be a string not "+(typeof src);
48
49             try {
50                 src = this.nibbleTitle(src);
51                 if (JSDOC.PluginManager) {
52                     JSDOC.PluginManager.run("onDocTagSynonym", this);
53                 }
54                 
55                 src = this.nibbleType(src);
56                 
57                 // only some tags are allowed to have names.
58                 if (this.title == "param" || this.title == "property" || this.title == "cfg") { // @config is deprecated
59                     src = this.nibbleName(src);
60                 }
61             }
62             catch(e) {
63                 if (JSDOC.opt.LOG) JSDOC.opt.LOG.warn(e);
64                 else throw e;
65             }
66             this.desc = src; // whatever is left
67             
68             // example tags need to have whitespace preserved
69             if (this.title != "example") this.desc = this.desc.trim();
70             
71             if (JSDOC.PluginManager) {
72                 JSDOC.PluginManager.run("onDocTag", this);
73             }
74         },
75
76         /**
77             Automatically called when this is stringified.
78          */
79         toString : function() {
80             return this.desc;
81         },
82          
83
84         /**
85             Find and shift off the title of a tag.
86             @param {string} src
87             @return src
88          */
89         nibbleTitle : function(src) {
90             if (typeof src != "string") throw "src must be a string not "+(typeof src);
91             
92             var parts = src.match(/^\s*(\S+)(?:\s([\s\S]*))?$/);
93
94             if (parts && parts[1]) this.title = parts[1];
95             if (parts && parts[2]) src = parts[2];
96             else src = "";
97             
98             return src;
99         },
100          
101         /**
102             Find and shift off the type of a tag.
103             @requires frame/String.js
104             @param {string} src
105             @return src
106          */
107         nibbleType : function(src) {
108             if (typeof src != "string") throw "src must be a string not "+(typeof src);
109             
110             if (src.match(/^\s*\{/)) {
111                 var typeRange = src.balance("{", "}");
112                 if (typeRange[1] == -1) {
113                     throw "Malformed comment tag ignored. Tag type requires an opening { and a closing }: "+src;
114                 }
115                 this.type = src.substring(typeRange[0]+1, typeRange[1]).trim();
116                 this.type = this.type.replace(/\s*,\s*/g, "|"); // multiples can be separated by , or |
117                 src = src.substring(typeRange[1]+1);
118             }
119             
120             return src;
121         },
122          
123
124         /**
125             Find and shift off the name of a tag.
126             @requires frame/String.js
127             @param {string} src
128             @return src
129          */
130         nibbleName : function(src) {
131             if (typeof src != "string") throw "src must be a string not "+(typeof src);
132             
133             src = src.trim();
134             
135             // is optional?
136             if (src.charAt(0) == "[") {
137                 var nameRange = src.balance("[", "]");
138                 if (nameRange[1] == -1) {
139                     throw "Malformed comment tag ignored. Tag optional name requires an opening [ and a closing ]: "+src;
140                 }
141                 this.name = src.substring(nameRange[0]+1, nameRange[1]).trim();
142                 this.isOptional = true;
143                 
144                 src = src.substring(nameRange[1]+1);
145                 
146                 // has default value?
147                 var nameAndValue = this.name.split("=");
148                 if (nameAndValue.length) {
149                     this.name = nameAndValue.shift().trim();
150                     this.defaultValue = nameAndValue.join("=");
151                 }
152             }
153             else {
154                 var parts = src.match(/^(\S+)(?:\s([\s\S]*))?$/);
155                 if (parts) {
156                     if (parts[1]) this.name = parts[1];
157                     if (parts[2]) src = parts[2].trim();
158                     else src = "";
159                 }
160             }   
161
162             return src;
163         }
164 });
165
166
167 JSDOC.DocTag.fromDump = function(t)
168 {
169     var ns = new JSDOC.DocTag();
170     for (var i in t) {
171         if (typeof(ns[i]) == "undefined") {
172             println("ERR:no default for DocTag:"+ i);
173         }
174        ns[i] = t[i];
175     }
176     return ns;
177 }