5 public enum DocTagTitle
50 errordomain DocTagException {
58 public class DocTag : Object
61 public DocTagTitle title = DocTagTitle.NO_VALUE;
62 public string type = ""; // eg.. boolean / string etc..., may be xxxx|bbbb - eg. optional types
63 public string name = ""; // eg. "title" << a property name etc...
64 public bool isOptional = false;
65 public string defaultValue = "";
66 public string desc = "";
67 public Gee.ArrayList<string> optvalues;
68 public string memberOf = ""; // set by add addMember..
70 public string asString()
72 return "DocTag: title=%s name=%s type=%s desc=%s".printf(
73 this.title.to_string(),
80 public Json.Object toJson()
82 var ret = new Json.Object();
83 ret.set_string_member("title", this.title.to_string());
84 ret.set_string_member("type", this.type);
85 ret.set_string_member("name", this.name);
86 ret.set_string_member("defaultValue", this.defaultValue);
87 ret.set_string_member("desc", this.desc);
88 ret.set_string_member("memberOf", this.memberOf);
89 ret.set_boolean_member("isOptional", this.isOptional);
90 var ar = new Json.Array();
91 foreach(var ov in this.optvalues) {
92 ar.add_string_element(ov);
94 ret.set_array_member("optvalues", ar);
99 public DocTag (string in_src)
102 GLib.debug("Parsing Tag: %s", in_src);
107 this.optvalues = new Gee.ArrayList<string>();
112 src = this.nibbleTitle(src);
114 src = this.nibbleType(src);
117 // only some tags are allowed to have names.
119 this.title == DocTagTitle.PARAM ||
120 this.title == DocTagTitle.PROPERTY ||
121 this.title == DocTagTitle.CFG) { // @config is deprecated
122 src = this.nibbleName(src);
125 catch(DocTagException e) {
126 GLib.debug("Failed to parse tag: '%s' = error = %s", in_src, e.message);
127 // only throw if in 'strict'??
132 // if type == @cfg, and matches (|....|...)
138 if (this.title == DocTagTitle.CFG && /^\([^)]+\)/.match_all(src, 0, out mi )) {
140 var ms = mi.fetch(0);
141 GLib.debug("Got Opt list: %s", ms);
143 ms = ms.substring(1,ms.length-2);
144 if (ms.contains("|")) {
145 var ar = ms.split("|");
146 for (var i =0 ; i < ar.length;i++) {
147 optvalues.add(ar[i].strip());
149 src = src.substring(ms.length, src.length - ms.length);
156 this.desc = src; // whatever is left
158 // example tags need to have whitespace preserved
159 if (this.title != DocTagTitle.EXAMPLE) {
160 this.desc = this.desc.strip();
171 Find and shift off the title of a tag.
175 private string nibbleTitle (string src) throws DocTagException
177 //GLib.debug("nibbleTitle: %s", src);
180 if(! /^\s*(\S+)\s*(?:\s([\s\S]*))?$/.match_full(src, src.length, 0, 0, out mi) ||
181 mi.get_match_count() < 2) {
182 throw new DocTagException.NO_TITLE("missing title");
186 //GLib.debug("nibbleTitle: regexmatches %d : %s",
187 // mi.get_match_count(),
188 // mi.fetch(1).up());
190 EnumClass enumc = (EnumClass) typeof (DocTagTitle).class_ref ();
192 unowned EnumValue? eval = enumc.get_value_by_name ( "JSDOC_DOC_TAG_TITLE_"+ mi.fetch(1).up());
194 throw new DocTagException.INVALID_TITLE("title not supported ??");
197 this.title = (DocTagTitle) eval.value;
198 return mi.get_match_count() > 2 ? mi.fetch(2) : "";
203 Find and shift off the type of a tag.
204 @requires frame/String.js
208 private string nibbleType(string src)
211 if(! /^\s*\{/.match_all(src, 0, out mi)) {
217 this.balance(src,'{', '}', out start, out stop);
218 //GLib.debug("nibble type: %s %d, %d", src, start,stop);
220 throw new DocTagException.INVALID_TYPE("Malformed comment tag ignored. Tag type requires an opening { and a closing }: ") ;
223 this.type = src.substring(start+1,stop-1).strip();
224 this.type = this.type.replace(",", "|"); // multiples can be separated by , or |
225 return src.substring(stop+1, -1);
232 Find and shift off the name of a tag.
233 @requires frame/String.js
237 private string nibbleName( string in_src) throws DocTagException
241 var src = in_src.strip();
242 //GLib.debug("nibbleName: %s", in_src);
245 if (src.get(0) == '[') {
247 this.balance(src,'[', ']', out start, out stop);
249 throw new DocTagException.INVALID_NAME("Malformed comment tag ignored. Tag optional name requires an opening [ and a closing ]: ");
252 this.name = src.substring(start+1, stop).strip();
253 this.isOptional = true;
255 src = src.substring(stop+1);
257 // has default value?
258 var nameAndValue = this.name.split("=");
259 if (nameAndValue.length > 1) {
260 var oname = this.name;
261 this.name = nameAndValue[0].strip();
263 this.defaultValue = oname.substring( nameAndValue[0].length + 1 , nameAndValue[0].length + 1 - oname.length); /// what about
265 GLib.debug("got name %s", this.name);
266 return src.substring(stop+1, stop+1-src.length);
268 // not encased with [ ]
272 if (/^(\S+)(?:\s([\s\S]*))?$/.match_full(src, src.length, 0, 0, out mi)) {
273 this.name = mi.fetch(1);
274 GLib.debug("got name %s", this.name);
275 return mi.get_match_count() > 2 ? mi.fetch(2) : "";
283 private void balance(string str, char open, char close, out int start, out int stop) {
286 while (str.get(start) != open) {
287 if (start == str.length) {
295 while (stop < str.length) {
296 if (str.get(stop) == open) balance++;
297 if (str.get(stop) == close) balance--;
298 if (balance == 0) break;
300 if (stop == str.length) {
309 public Json.Array optvalue_as_json_array()
311 var ret = new Json.Array();
312 foreach (var str in this.optvalues ) {
313 ret.add_string_element(str);