Fix #6894 - debugging generator
[roojspacker] / roojspacker / DocComment.vala
1  
2 /**
3  * Create a new DocComment. This takes a raw documentation comment,
4  * and wraps it in useful accessors.
5  * @class Represents a documentation comment object.
6  * 
7  */ 
8  
9 namespace JSDOC 
10 {
11         public class DocComment : Object
12         {
13  
14                 public bool isUserComment  = true;
15                 public bool hasTags             = false;
16                 public string src          = "";
17                 //string meta       =  "";
18                 //Gee.ArrayList<string> tagTexts;
19                 public Gee.ArrayList<DocTag>    tags;
20         
21                 static GLib.Regex has_tag_regex;
22                 static GLib.Regex tag_regex;
23                 static GLib.Regex comment_line_start_regex;
24                 static GLib.Regex comment_line_start_white_space_regex;
25                 static GLib.Regex comment_needs_desc_regex;
26                  /**
27                  * Used to store the currently shared tag text.
28                  * not sure where we use this yet..
29                  * but i think it's related to merging multiple comments together...
30                  */
31
32                 public static string    shared = "";
33                 
34                 static bool done_init = false;
35         
36                 static void initRegex()
37                 {
38                         if (DocComment.done_init) {
39                                 return;
40                         }
41                         DocComment.has_tag_regex = new GLib.Regex("^\\s*@\\s*\\S+"); // multiline?
42
43                         DocComment.tag_regex = new GLib.Regex("(^|[\\r\\n])\\s*@"); // empty line, then @ or starting with @?
44                         
45
46                         DocComment.comment_line_start_regex = new GLib.Regex("(^\\/\\*\\*|\\*\\/$)");
47                         DocComment.comment_line_start_white_space_regex = new GLib.Regex("\\s*\\* ?");
48                         DocComment.comment_needs_desc_regex = new GLib.Regex("\\s*@(class|event|property)");
49                         
50                         DocComment.done_init = true;
51                 }
52          
53                 public DocComment (string comment = "") 
54                 {
55                     
56                     DocComment.initRegex();
57                      
58                     GLib.debug("parse comment : %s", comment);
59                     this.tags          = new Gee.ArrayList<DocTag>();
60
61                     
62                  
63                 if (comment.strip() == "") {
64                     comment = "/** @desc */";
65                     this.isUserComment = false;
66                 }
67                 
68                 this.src = DocComment.unwrapComment(comment);
69                 
70                 //println(this.src);
71                 
72                 // looks like #+ support???
73                 /*
74                 this.meta = "";
75                 if (this.src.indexOf("#") == 0) {
76                     this.src.match(/#(.+[+-])([\s\S]*)$/);
77                     if (RegExp.$1) this.meta = RegExp.$1;
78                     if (RegExp.$2) this.src = RegExp.$2;
79                 }
80                 */
81                 this.hasTags = /^\s*@\s*\S+/.match(this.src);
82
83                 this.fixDesc();
84                 
85                 //if (typeof JSDOC.PluginManager != "undefined") {
86                 //    JSDOC.PluginManager.run("onDocCommentSrc", this);
87                 //}
88                 
89                 this.src = DocComment.shared+"\n"+this.src;
90
91                         //var tagTexts      = new Gee.ArrayList<string>();
92  
93                 
94                 var bits = /(^|[\r\n])\s*@/.split(this.src);
95                         for(int i=0; i<bits.length; i++) {
96                                 var sa = bits[i];
97                                 if (sa.strip().length >0) {
98                                         this.tags.add(new DocTag(sa));
99                                         // tagTexts.add(sa); // ?? strip again?
100                                 }
101                         }
102                         
103                                         
104                 
105             }
106                 
107                    
108                     
109                 /**
110                  * Remove slash-star comment wrapper from a raw comment string.
111                  *  @type String
112                  */
113                 public static string  unwrapComment( string comment) 
114                 {
115                      if (comment.length < 1) {
116                                  return "";
117                          }
118                          
119                          var ret = /^\/\*\*|\*\/$/.replace(
120                                         comment, comment.length, 0, "", 0 ); //GLib.RegexMatchFlags.NEWLINE_ANYCRLF );
121                          
122                          ret = /(^|[\r\n])\s*\* ?/.replace(ret, ret.length, 0, "\n"  ); //);
123                      
124                     return ret.strip();
125                  }
126             /**
127                 If no @desc tag is provided, this function will add it.
128              */
129             void fixDesc() 
130             {
131                 //if (this.meta && this.meta != "@+") return;
132                 
133                 
134                 
135                 // does not have any @ lines..
136                 // -- skip comments without @!!
137                 if (!this.hasTags) {
138                     this.src = "@desc "+ this.src;
139                     // TAGS that are not \n prefixed!! ...
140                     // does not make sense....???
141                     //this.src = this.src.replace(/@\s*type/g, '\n@type'); 
142                 
143                     return;
144                 }
145                 // kdludge for stuff...
146                 //this.src = this.src.replace(/@\s*type/g, '\n@type'); 
147                 
148                 // only apply @desc fix to classes..
149                 if (!DocComment.comment_needs_desc_regex.match(this.src,GLib.RegexMatchFlags.NEWLINE_ANYCRLF) ) {
150                     return;
151                 }
152                 // if no desc - add it on the first line that is not a @
153                 var lines = this.src.split("\n");
154                 var nsrc = "";
155                 var gotf = false;
156                 
157                 for(var i =0; i < lines.length;i++) {
158                     var line = lines[i];
159                     if (gotf) {
160                         nsrc += line + "\n";
161                         continue;
162                     }
163                     if (DocComment.has_tag_regex.match(line)) { // line with @
164                         nsrc += line + "\n";
165                         continue;
166                     }
167                     gotf = true;
168                     nsrc += "@desc " + line + "\n";
169                     
170                 }
171                  
172                 this.src = nsrc;
173                 
174                  
175                 
176             }
177                   
178                  
179             public Gee.ArrayList<DocTag> getTag ( DocTagTitle tagTitle) {
180                         var ret = new Gee.ArrayList<DocTag>();
181                 foreach(var tag in this.tags) {
182                         if (tag.title == tagTitle) {
183                                 ret.add(tag);
184                         }
185                         }
186                         return ret;
187             }
188              public string getTagAsString ( DocTagTitle tagTitle) {
189                         string[] ret =  {};
190                 foreach(var tag in this.tags) {
191                         if (tag.title == tagTitle) {
192                                 ret += tag.desc;
193                         }
194                         }
195                         return string.joinv("\n", ret);
196             }
197             
198             public Json.Object toJson()
199                 {
200                         var ret = new Json.Object();
201                         ret.set_string_member("src", this.src);
202                         var ar = new Json.Array();
203                         foreach(var a in this.tags) {
204                                 ar.add_object_element(a.toJson());
205                         }
206                         ret.set_array_member("tags", ar);
207                         ret.set_boolean_member("isUserComment", this.isUserComment);                    
208                         ret.set_boolean_member("hasTags", this.hasTags);                                                
209                         return ret;
210                 }
211         
212         }
213 }
214