@@ -52,7 +52,7 @@ function assert(
5252 condition : boolean ,
5353 message : string ,
5454 document : { location : Location } ,
55- ) {
55+ ) : asserts condition {
5656 if ( ! condition ) {
5757 diagnostics . push ( new DocumentError ( message , document ) ) ;
5858 }
@@ -77,18 +77,17 @@ function isVoid(returnType: TsTypeDef) {
7777
7878function assertHasReturnTag ( document : { jsDoc : JsDoc ; location : Location } ) {
7979 const tag = document . jsDoc . tags ?. find ( ( tag ) => tag . kind === "return" ) ;
80- if ( tag === undefined ) {
81- diagnostics . push (
82- new DocumentError ( "Symbol must have a @return or @returns tag" , document ) ,
83- ) ;
84- } else {
85- assert (
86- // @ts -ignore doc is defined
87- tag . doc !== undefined ,
88- "@return tag must have a description" ,
89- document ,
90- ) ;
91- }
80+ assert (
81+ tag !== undefined ,
82+ "Symbol must have a @return or @returns tag" ,
83+ document ,
84+ ) ;
85+ if ( tag === undefined ) return ;
86+ assert (
87+ tag . doc !== undefined ,
88+ "@return tag must have a description" ,
89+ document ,
90+ ) ;
9291}
9392
9493/**
@@ -111,14 +110,11 @@ function assertHasParamDefinition(
111110 return false ;
112111 } ) ;
113112
114- if ( ! paramDoc ) {
115- diagnostics . push (
116- new DocumentError (
117- `@param ${ param . name } must have a corresponding named function parameter definition.` ,
118- document ,
119- ) ,
120- ) ;
121- }
113+ assert (
114+ paramDoc !== undefined ,
115+ `@param ${ param . name } must have a corresponding function parameter definition.` ,
116+ document ,
117+ ) ;
122118}
123119
124120function assertHasParamTag (
@@ -128,37 +124,31 @@ function assertHasParamTag(
128124 const tag = document . jsDoc . tags ?. find ( ( tag ) =>
129125 tag . kind === "param" && tag . name === param
130126 ) ;
131- if ( ! tag ) {
132- diagnostics . push (
133- new DocumentError ( `Symbol must have a @param tag for ${ param } ` , document ) ,
134- ) ;
135- } else {
136- assert (
137- // @ts -ignore doc is defined
138- tag . doc !== undefined ,
139- `@param tag for ${ param } must have a description` ,
140- document ,
141- ) ;
142- }
127+ assert (
128+ tag !== undefined ,
129+ `Symbol must have a @param tag for ${ param } ` ,
130+ document ,
131+ ) ;
132+ if ( tag === undefined ) return ;
133+ assert (
134+ // @ts -ignore doc is defined
135+ tag . doc !== undefined ,
136+ `@param tag for ${ param } must have a description` ,
137+ document ,
138+ ) ;
143139}
144140
145141function assertHasSnippets (
146142 doc : string ,
147143 document : { jsDoc : JsDoc ; location : Location } ,
148- required = true ,
149144) {
150145 const snippets = doc . match ( TS_SNIPPET ) ;
151- if ( snippets === null ) {
152- if ( required ) {
153- diagnostics . push (
154- new DocumentError (
155- "@example tag must have a TypeScript code snippet" ,
156- document ,
157- ) ,
158- ) ;
159- }
160- return ;
161- }
146+ assert (
147+ snippets !== null ,
148+ "@example tag must have a TypeScript code snippet" ,
149+ document ,
150+ ) ;
151+ if ( snippets === null ) return ;
162152 for ( let snippet of snippets ) {
163153 const delim = snippet . split ( NEWLINE ) [ 0 ] ;
164154 // Trim the code block delimiters
@@ -179,17 +169,7 @@ function assertHasExampleTag(
179169 const exampleTags = document . jsDoc . tags ?. filter ( ( tag ) =>
180170 tag . kind === "example"
181171 ) as JsDocTagDocRequired [ ] ;
182- const hasNoExampleTags = exampleTags === undefined ||
183- exampleTags . length === 0 ;
184- if (
185- hasNoExampleTags &&
186- ! document . jsDoc . tags ?. some ( ( tag ) => tag . kind === "private" )
187- ) {
188- diagnostics . push (
189- new DocumentError ( "Symbol must have an @example tag" , document ) ,
190- ) ;
191- return ;
192- }
172+ assert ( exampleTags ?. length > 0 , "Symbol must have an @example tag" , document ) ;
193173 for ( const tag of exampleTags ) {
194174 assert (
195175 tag . doc !== undefined ,
@@ -216,21 +196,17 @@ function assertHasTypeParamTags(
216196 const tag = document . jsDoc . tags ?. find ( ( tag ) =>
217197 tag . kind === "template" && tag . name === typeParamName
218198 ) ;
219- if ( tag === undefined ) {
220- diagnostics . push (
221- new DocumentError (
222- `Symbol must have a @typeParam tag for ${ typeParamName } ` ,
223- document ,
224- ) ,
225- ) ;
226- } else {
227- assert (
228- // @ts -ignore doc is defined
229- tag . doc !== undefined ,
230- `@typeParam tag for ${ typeParamName } must have a description` ,
231- document ,
232- ) ;
233- }
199+ assert (
200+ tag !== undefined ,
201+ `Symbol must have a @typeParam tag for ${ typeParamName } ` ,
202+ document ,
203+ ) ;
204+ assert (
205+ // @ts -ignore doc is defined
206+ tag . doc !== undefined ,
207+ `@typeParam tag for ${ typeParamName } must have a description` ,
208+ document ,
209+ ) ;
234210}
235211
236212/**
@@ -245,7 +221,6 @@ function assertHasTypeParamTags(
245221function assertFunctionDocs (
246222 document : DocNodeWithJsDoc < DocNodeFunction | ClassMethodDef > ,
247223) {
248- assertHasSnippets ( document . jsDoc . doc ! , document , false ) ;
249224 for ( const param of document . functionDef . params ) {
250225 if ( param . kind === "identifier" ) {
251226 assertHasParamTag ( document , param . name ) ;
@@ -289,7 +264,6 @@ function assertFunctionDocs(
289264 * - Documentation on all properties, methods, and constructors.
290265 */
291266function assertClassDocs ( document : DocNodeWithJsDoc < DocNodeClass > ) {
292- assertHasSnippets ( document . jsDoc . doc ! , document , false ) ;
293267 for ( const typeParam of document . classDef . typeParams ) {
294268 assertHasTypeParamTags ( document , typeParam . name ) ;
295269 }
@@ -299,41 +273,31 @@ function assertClassDocs(document: DocNodeWithJsDoc<DocNodeClass>) {
299273
300274 for ( const property of document . classDef . properties ) {
301275 if ( property . jsDoc === undefined ) continue ; // this is caught by `deno doc --lint`
302- if ( property . accessibility !== undefined ) {
303- diagnostics . push (
304- new DocumentError (
305- "Do not use `public`, `protected`, or `private` fields in classes" ,
306- property ,
307- ) ,
308- ) ;
309- continue ;
310- }
276+ assert (
277+ property . accessibility === undefined ,
278+ "Do not use `public`, `protected`, or `private` fields in classes" ,
279+ property ,
280+ ) ;
311281 assertClassPropertyDocs (
312282 property as DocNodeWithJsDoc < ClassPropertyDef > ,
313283 ) ;
314284 }
315285 for ( const method of document . classDef . methods ) {
316286 if ( method . jsDoc === undefined ) continue ; // this is caught by `deno doc --lint`
317- if ( method . accessibility !== undefined ) {
318- diagnostics . push (
319- new DocumentError (
320- "Do not use `public`, `protected`, or `private` methods in classes" ,
321- method ,
322- ) ,
323- ) ;
324- }
287+ assert (
288+ method . accessibility === undefined ,
289+ "Do not use `public`, `protected`, or `private` methods in classes" ,
290+ document ,
291+ ) ;
325292 assertFunctionDocs ( method as DocNodeWithJsDoc < ClassMethodDef > ) ;
326293 }
327294 for ( const constructor of document . classDef . constructors ) {
328295 if ( constructor . jsDoc === undefined ) continue ; // this is caught by `deno doc --lint`
329- if ( constructor . accessibility !== undefined ) {
330- diagnostics . push (
331- new DocumentError (
332- "Do not use `public`, `protected`, or `private` constructors in classes" ,
333- constructor ,
334- ) ,
335- ) ;
336- }
296+ assert (
297+ constructor . accessibility === undefined ,
298+ "Do not use `public`, `protected`, or `private` constructors in classes" ,
299+ constructor ,
300+ ) ;
337301 assertConstructorDocs (
338302 constructor as DocNodeWithJsDoc < ClassConstructorDef > ,
339303 ) ;
@@ -392,14 +356,11 @@ function assertModuleDoc(document: DocNodeWithJsDoc<DocNodeModuleDoc>) {
392356function assertHasDefaultTags ( document : DocNodeWithJsDoc < DocNodeInterface > ) {
393357 for ( const prop of document . interfaceDef . properties ) {
394358 if ( ! prop . optional ) continue ;
395- if ( ! prop . jsDoc ?. tags ?. find ( ( tag ) => tag . kind === "default" ) ) {
396- diagnostics . push (
397- new DocumentError (
398- "Optional interface properties should have default values" ,
399- document ,
400- ) ,
401- ) ;
402- }
359+ assert (
360+ prop . jsDoc ?. tags ?. find ( ( tag ) => tag . kind === "default" ) !== undefined ,
361+ "Optional interface properties should have default values" ,
362+ document ,
363+ ) ;
403364 }
404365}
405366
@@ -417,14 +378,11 @@ function assertHasDeprecationDesc(document: DocNodeWithJsDoc<DocNode>) {
417378 if ( ! tags ) return ;
418379 for ( const tag of tags ) {
419380 if ( tag . kind !== "deprecated" ) continue ;
420- if ( tag . doc === undefined ) {
421- diagnostics . push (
422- new DocumentError (
423- "@deprecated tag must have a description" ,
424- document ,
425- ) ,
426- ) ;
427- }
381+ assert (
382+ tag . doc !== undefined ,
383+ "@deprecated tag must have a description" ,
384+ document ,
385+ ) ;
428386 }
429387}
430388
@@ -434,30 +392,24 @@ async function assertDocs(specifiers: string[]) {
434392 if ( d . jsDoc === undefined || d . declarationKind !== "export" ) continue ; // this is caught by other checks
435393
436394 const document = d as DocNodeWithJsDoc < DocNode > ;
395+ assertHasDeprecationDesc ( document ) ;
437396 switch ( document . kind ) {
438397 case "moduleDoc" : {
439398 if ( document . location . filename . endsWith ( "/mod.ts" ) ) {
440399 assertModuleDoc ( document ) ;
441- assertHasDeprecationDesc ( document ) ;
442400 }
443401 break ;
444402 }
445403 case "function" : {
446404 assertFunctionDocs ( document ) ;
447- assertHasDeprecationDesc ( document ) ;
448405 break ;
449406 }
450407 case "class" : {
451408 assertClassDocs ( document ) ;
452- assertHasDeprecationDesc ( document ) ;
453409 break ;
454410 }
455411 case "interface" :
456412 assertInterfaceDocs ( document ) ;
457- assertHasDeprecationDesc ( document ) ;
458- break ;
459- case "variable" :
460- assertHasDeprecationDesc ( document ) ;
461413 break ;
462414 }
463415 }
0 commit comments