Commit | Line | Data |
---|---|---|
629a09ae DV |
1 | if (typeof JSDOC == "undefined") JSDOC = {}; |
2 | ||
3 | /** | |
4 | Create a new DocComment. This takes a raw documentation comment, | |
5 | and wraps it in useful accessors. | |
6 | @class Represents a documentation comment object. | |
7 | */ | |
8 | JSDOC.DocComment = function(/**String*/comment) { | |
9 | this.init(); | |
10 | if (typeof comment != "undefined") { | |
11 | this.parse(comment); | |
12 | } | |
13 | } | |
14 | ||
15 | JSDOC.DocComment.prototype.init = function() { | |
16 | this.isUserComment = true; | |
17 | this.src = ""; | |
18 | this.meta = ""; | |
19 | this.tagTexts = []; | |
20 | this.tags = []; | |
21 | } | |
22 | ||
23 | /** | |
24 | @requires JSDOC.DocTag | |
25 | */ | |
26 | JSDOC.DocComment.prototype.parse = function(/**String*/comment) { | |
27 | if (comment == "") { | |
28 | comment = "/** @desc */"; | |
29 | this.isUserComment = false; | |
30 | } | |
31 | ||
32 | this.src = JSDOC.DocComment.unwrapComment(comment); | |
33 | ||
34 | this.meta = ""; | |
35 | if (this.src.indexOf("#") == 0) { | |
36 | this.src.match(/#(.+[+-])([\s\S]*)$/); | |
37 | if (RegExp.$1) this.meta = RegExp.$1; | |
38 | if (RegExp.$2) this.src = RegExp.$2; | |
39 | } | |
40 | ||
41 | if (typeof JSDOC.PluginManager != "undefined") { | |
42 | JSDOC.PluginManager.run("onDocCommentSrc", this); | |
43 | } | |
44 | ||
45 | this.fixDesc(); | |
46 | ||
47 | this.src = JSDOC.DocComment.shared+"\n"+this.src; | |
48 | ||
49 | this.tagTexts = | |
50 | this.src | |
51 | .split(/(^|[\r\n])\s*@/) | |
52 | .filter(function($){return $.match(/\S/)}); | |
53 | ||
54 | /** | |
55 | The tags found in the comment. | |
56 | @type JSDOC.DocTag[] | |
57 | */ | |
58 | this.tags = this.tagTexts.map(function($){return new JSDOC.DocTag($)}); | |
59 | ||
60 | if (typeof JSDOC.PluginManager != "undefined") { | |
61 | JSDOC.PluginManager.run("onDocCommentTags", this); | |
62 | } | |
63 | } | |
64 | ||
65 | /*t: | |
66 | plan(5, "testing JSDOC.DocComment"); | |
67 | requires("../frame/String.js"); | |
68 | requires("../lib/JSDOC/DocTag.js"); | |
69 | ||
70 | var com = new JSDOC.DocComment("/**@foo some\n* comment here*"+"/"); | |
71 | is(com.tagTexts[0], "foo some\ncomment here", "first tag text is found."); | |
72 | is(com.tags[0].title, "foo", "the title is found in a comment with one tag."); | |
73 | ||
74 | var com = new JSDOC.DocComment("/** @foo first\n* @bar second*"+"/"); | |
75 | is(com.getTag("bar").length, 1, "getTag() returns one tag by that title."); | |
76 | ||
77 | JSDOC.DocComment.shared = "@author John Smith"; | |
78 | var com = new JSDOC.DocComment("/**@foo some\n* comment here*"+"/"); | |
79 | is(com.tags[0].title, "author", "shared comment is added."); | |
80 | is(com.tags[1].title, "foo", "shared comment is added to existing tag."); | |
81 | */ | |
82 | ||
83 | /** | |
84 | If no @desc tag is provided, this function will add it. | |
85 | */ | |
86 | JSDOC.DocComment.prototype.fixDesc = function() { | |
87 | if (this.meta && this.meta != "@+") return; | |
88 | if (/^\s*[^@\s]/.test(this.src)) { | |
89 | this.src = "@desc "+this.src; | |
90 | } | |
91 | } | |
92 | ||
93 | /*t: | |
94 | plan(5, "testing JSDOC.DocComment#fixDesc"); | |
95 | ||
96 | var com = new JSDOC.DocComment(); | |
97 | ||
98 | com.src = "this is a desc\n@author foo"; | |
99 | com.fixDesc(); | |
100 | is(com.src, "@desc this is a desc\n@author foo", "if no @desc tag is provided one is added."); | |
101 | ||
102 | com.src = "x"; | |
103 | com.fixDesc(); | |
104 | is(com.src, "@desc x", "if no @desc tag is provided one is added to a single character."); | |
105 | ||
106 | com.src = "\nx"; | |
107 | com.fixDesc(); | |
108 | is(com.src, "@desc \nx", "if no @desc tag is provided one is added to return and character."); | |
109 | ||
110 | com.src = " "; | |
111 | com.fixDesc(); | |
112 | is(com.src, " ", "if no @desc tag is provided one is not added to just whitespace."); | |
113 | ||
114 | com.src = ""; | |
115 | com.fixDesc(); | |
116 | is(com.src, "", "if no @desc tag is provided one is not added to empty."); | |
117 | */ | |
118 | ||
119 | /** | |
120 | Remove slash-star comment wrapper from a raw comment string. | |
121 | @type String | |
122 | */ | |
123 | JSDOC.DocComment.unwrapComment = function(/**String*/comment) { | |
124 | if (!comment) return ""; | |
125 | var unwrapped = comment.replace(/(^\/\*\*|\*\/$)/g, "").replace(/^\s*\* ?/gm, ""); | |
126 | return unwrapped; | |
127 | } | |
128 | ||
129 | /*t: | |
130 | plan(5, "testing JSDOC.DocComment.unwrapComment"); | |
131 | ||
132 | var com = "/**x*"+"/"; | |
133 | var unwrapped = JSDOC.DocComment.unwrapComment(com); | |
134 | is(unwrapped, "x", "a single character jsdoc is found."); | |
135 | ||
136 | com = "/***x*"+"/"; | |
137 | unwrapped = JSDOC.DocComment.unwrapComment(com); | |
138 | is(unwrapped, "x", "three stars are allowed in the opener."); | |
139 | ||
140 | com = "/****x*"+"/"; | |
141 | unwrapped = JSDOC.DocComment.unwrapComment(com); | |
142 | is(unwrapped, "*x", "fourth star in the opener is kept."); | |
143 | ||
144 | com = "/**x\n * y\n*"+"/"; | |
145 | unwrapped = JSDOC.DocComment.unwrapComment(com); | |
146 | is(unwrapped, "x\ny\n", "leading stars and spaces are trimmed."); | |
147 | ||
148 | com = "/**x\n * y\n*"+"/"; | |
149 | unwrapped = JSDOC.DocComment.unwrapComment(com); | |
150 | is(unwrapped, "x\n y\n", "only first space after leading stars are trimmed."); | |
151 | */ | |
152 | ||
153 | /** | |
154 | Provides a printable version of the comment. | |
155 | @type String | |
156 | */ | |
157 | JSDOC.DocComment.prototype.toString = function() { | |
158 | return this.src; | |
159 | } | |
160 | ||
161 | /*t: | |
162 | plan(1, "testing JSDOC.DocComment#fixDesc"); | |
163 | var com = new JSDOC.DocComment(); | |
164 | com.src = "foo"; | |
165 | is(""+com, "foo", "stringifying a comment returns the unwrapped src."); | |
166 | */ | |
167 | ||
168 | /** | |
169 | Given the title of a tag, returns all tags that have that title. | |
170 | @type JSDOC.DocTag[] | |
171 | */ | |
172 | JSDOC.DocComment.prototype.getTag = function(/**String*/tagTitle) { | |
173 | return this.tags.filter(function($){return $.title == tagTitle}); | |
174 | } | |
175 | ||
176 | JSDOC.DocComment.prototype.deleteTag = function(/**String*/tagTitle) { | |
177 | this.tags = this.tags.filter(function($){return $.title != tagTitle}) | |
178 | } | |
179 | ||
180 | /*t: | |
181 | plan(1, "testing JSDOC.DocComment#getTag"); | |
182 | requires("../frame/String.js"); | |
183 | requires("../lib/JSDOC/DocTag.js"); | |
184 | ||
185 | var com = new JSDOC.DocComment("/**@foo some\n* @bar\n* @bar*"+"/"); | |
186 | is(com.getTag("bar").length, 2, "getTag returns expected number of tags."); | |
187 | */ | |
188 | ||
189 | /** | |
190 | Used to store the currently shared tag text. | |
191 | */ | |
192 | JSDOC.DocComment.shared = ""; | |
193 | ||
194 | /*t: | |
195 | plan(2, "testing JSDOC.DocComment.shared"); | |
196 | requires("../frame/String.js"); | |
197 | requires("../lib/JSDOC/DocTag.js"); | |
198 | ||
199 | JSDOC.DocComment.shared = "@author Michael"; | |
200 | ||
201 | var com = new JSDOC.DocComment("/**@foo\n* @foo*"+"/"); | |
202 | is(com.getTag("author").length, 1, "getTag returns shared tag."); | |
203 | is(com.getTag("foo").length, 2, "getTag returns unshared tags too."); | |
204 | */ |