5 public enum DocTagTitle
48 // these are some we have added for creating trees etc..
49 CHILDREN, // what classes can be added as child in a tree
50 PARENT, // restrict what the class can be added to.
51 ABSTRACT, // is the class abstract
52 BUILDER_TOP // can the element be used as a top level in the gui builder
57 errordomain DocTagException {
65 public class DocTag : Object
68 public DocTagTitle title = DocTagTitle.NO_VALUE;
69 public string type = ""; // eg.. boolean / string etc..., may be xxxx|bbbb - eg. optional types
70 public string name = ""; // eg. "title" << a property name etc...
71 public bool isOptional = false;
72 public string defaultValue = "";
73 public string desc = "";
74 public Gee.ArrayList<string> optvalues;
75 public string memberOf = ""; // set by add addMember..
77 public string asString()
79 return "DocTag: title=%s name=%s type=%s desc=%s".printf(
80 this.title.to_string(),
87 public Json.Object toJson()
89 var ret = new Json.Object();
90 ret.set_string_member("title", this.title.to_string());
91 ret.set_string_member("type", this.type);
92 ret.set_string_member("name", this.name);
93 ret.set_string_member("defaultValue", this.defaultValue);
94 ret.set_string_member("desc", this.desc);
95 ret.set_string_member("memberOf", this.memberOf);
96 ret.set_boolean_member("isOptional", this.isOptional);
97 var ar = new Json.Array();
98 foreach(var ov in this.optvalues) {
99 ar.add_string_element(ov);
101 ret.set_array_member("optvalues", ar);
106 public DocTag (string in_src)
109 GLib.debug("Parsing Tag: %s", in_src);
114 this.optvalues = new Gee.ArrayList<string>();
119 src = this.nibbleTitle(src);
121 src = this.nibbleType(src);
124 // only some tags are allowed to have names.
126 this.title == DocTagTitle.PARAM ||
127 this.title == DocTagTitle.PROPERTY ||
128 this.title == DocTagTitle.CFG) { // @config is deprecated
129 src = this.nibbleName(src);
132 catch(DocTagException e) {
133 GLib.debug("Failed to parse tag: '%s' = error = %s", in_src, e.message);
134 // only throw if in 'strict'??
139 // if type == @cfg, and matches (|....|...)
145 if (this.title == DocTagTitle.CFG && /^\([^)]+\)/.match_all(src, 0, out mi )) {
147 var ms = mi.fetch(0);
148 GLib.debug("Got Opt list: %s", ms);
150 ms = ms.substring(1,ms.length-2);
151 if (ms.contains("|")) {
152 var ar = ms.split("|");
153 for (var i =0 ; i < ar.length;i++) {
154 optvalues.add(ar[i].strip());
156 src = src.substring(ms.length, src.length - ms.length);
163 this.desc = src; // whatever is left
165 // example tags need to have whitespace preserved
166 if (this.title != DocTagTitle.EXAMPLE) {
167 this.desc = this.desc.strip();
178 Find and shift off the title of a tag.
182 private string nibbleTitle (string src) throws DocTagException
184 //GLib.debug("nibbleTitle: %s", src);
187 if(! /^\s*(\S+)\s*(?:\s([\s\S]*))?$/.match_full(src, src.length, 0, 0, out mi) ||
188 mi.get_match_count() < 2) {
189 throw new DocTagException.NO_TITLE("missing title");
193 // convert the @xxx to a DocTagTitle
194 // wonder if caching this as a GeeHashmap would be quicker?
196 EnumClass enumc = (EnumClass) typeof (DocTagTitle).class_ref ();
198 unowned EnumValue? eval = enumc.get_value_by_name(
199 // "JSDOC_DOC_TAG_TITLE_"+ mi.fetch(1).up()
200 "JSDOC_DOC_TAG_TITLE_"+ mi.fetch(1).up().replace("-", "_")
203 throw new DocTagException.INVALID_TITLE("title not supported ??");
206 this.title = (DocTagTitle) eval.value;
207 return mi.get_match_count() > 2 ? mi.fetch(2) : "";
212 Find and shift off the type of a tag.
213 @requires frame/String.js
217 private string nibbleType(string src)
220 if(! /^\s*\{/.match_all(src, 0, out mi)) {
226 this.balance(src,'{', '}', out start, out stop);
227 //GLib.debug("nibble type: %s %d, %d", src, start,stop);
229 throw new DocTagException.INVALID_TYPE("Malformed comment tag ignored. Tag type requires an opening { and a closing }: ") ;
232 this.type = src.substring(start+1,stop-1).strip();
233 this.type = this.type.replace(",", "|"); // multiples can be separated by , or |
234 return src.substring(stop+1, -1);
241 Find and shift off the name of a tag.
242 @requires frame/String.js
246 private string nibbleName( string in_src) throws DocTagException
250 var src = in_src.strip();
251 //GLib.debug("nibbleName: %s", in_src);
254 if (src.get(0) == '[') {
256 this.balance(src,'[', ']', out start, out stop);
258 throw new DocTagException.INVALID_NAME("Malformed comment tag ignored. Tag optional name requires an opening [ and a closing ]: ");
261 this.name = src.substring(start+1, stop).strip();
262 this.isOptional = true;
264 src = src.substring(stop+1);
266 // has default value?
267 var nameAndValue = this.name.split("=");
268 if (nameAndValue.length > 1) {
269 var oname = this.name;
270 this.name = nameAndValue[0].strip();
272 this.defaultValue = oname.substring( nameAndValue[0].length + 1 , nameAndValue[0].length + 1 - oname.length); /// what about
274 GLib.debug("got name %s", this.name);
275 return src.substring(stop+1, stop+1-src.length);
277 // not encased with [ ]
281 if (/^(\S+)(?:\s([\s\S]*))?$/.match_full(src, src.length, 0, 0, out mi)) {
282 this.name = mi.fetch(1);
283 GLib.debug("got name %s", this.name);
284 return mi.get_match_count() > 2 ? mi.fetch(2) : "";
292 private void balance(string str, char open, char close, out int start, out int stop) {
295 while (str.get(start) != open) {
296 if (start == str.length) {
304 while (stop < str.length) {
305 if (str.get(stop) == open) balance++;
306 if (str.get(stop) == close) balance--;
307 if (balance == 0) break;
309 if (stop == str.length) {
318 public Json.Array optvalue_as_json_array()
320 var ret = new Json.Array();
321 foreach (var str in this.optvalues ) {
322 ret.add_string_element(str);
328 public Json.Object toPropertyJSON (Symbol parent)
331 var add = new Json.Object();
332 add.set_string_member("name",this.name);
333 add.set_string_member("type",this.type);
334 add.set_string_member("desc",this.desc);
335 add.set_string_member("memberOf", this.memberOf == parent.alias ? "" : this.memberOf);