@@ -7,7 +7,7 @@ import log4js = require('log4js');
77import path = require( 'path' ) ;
88import ts = require( 'typescript' ) ;
99import { JSII_DIAGNOSTICS_CODE } from './compiler' ;
10- import { parseSymbolDocumentation } from './docs' ;
10+ import { getReferencedDocParams , parseSymbolDocumentation } from './docs' ;
1111import { Diagnostic , Emitter } from './emitter' ;
1212import literate = require( './literate' ) ;
1313import { ProjectInfo } from './project-info' ;
@@ -645,18 +645,10 @@ export class Assembler implements Emitter {
645645 }
646646
647647 /**
648- * Register documentations on a ``spec.Documentable`` entry.
649- *
650- * @param sym the symbol holding the JSDoc information
651- * @param documentable the entity being documented
652- *
653- * @returns ``documentable``
648+ * Return docs for a symbol
654649 */
655650 private _visitDocumentation ( sym : ts . Symbol ) : spec . Docs | undefined {
656- const comment = ts . displayPartsToString ( sym . getDocumentationComment ( this . _typeChecker ) ) . trim ( ) ;
657-
658- // Right here we'll just guess that the first declaration site is the most important one.
659- const result = parseSymbolDocumentation ( comment , sym . getJsDocTags ( ) ) ;
651+ const result = parseSymbolDocumentation ( sym , this . _typeChecker ) ;
660652
661653 for ( const diag of result . diagnostics || [ ] ) {
662654 this . _diagnostic ( sym . declarations [ 0 ] ,
@@ -669,6 +661,20 @@ export class Assembler implements Emitter {
669661 return ! allUndefined ? result . docs : undefined ;
670662 }
671663
664+ /**
665+ * Check that all parameters the doc block refers to with a @param declaration actually exist
666+ */
667+ private _validateReferencedDocParams ( method : spec . Method , methodSym : ts . Symbol ) {
668+ const params = getReferencedDocParams ( methodSym ) ;
669+ const actualNames = new Set ( ( method . parameters || [ ] ) . map ( p => p . name ) ) ;
670+ for ( const param of params ) {
671+ if ( ! actualNames . has ( param ) ) {
672+ this . _diagnostic ( methodSym . valueDeclaration , ts . DiagnosticCategory . Warning ,
673+ `In doc block of '${ method . name } ', '@param ${ param } ' refers to a nonexistent parameter.` ) ;
674+ }
675+ }
676+ }
677+
672678 private async _visitInterface ( type : ts . Type , namespace : string [ ] ) : Promise < spec . InterfaceType | undefined > {
673679 if ( LOG . isTraceEnabled ( ) ) {
674680 LOG . trace ( `Processing interface: ${ colors . gray ( namespace . join ( '.' ) ) } .${ colors . cyan ( type . symbol . name ) } ` ) ;
@@ -846,6 +852,8 @@ export class Assembler implements Emitter {
846852 } ) ;
847853 }
848854
855+ this . _validateReferencedDocParams ( method , symbol ) ;
856+
849857 type . methods = type . methods || [ ] ;
850858 if ( type . methods . find ( m => m . name === method . name && m . static === method . static ) != null ) {
851859 LOG . trace ( `Dropping re-declaration of ${ colors . green ( type . fqn ) } #${ colors . cyan ( method . name ! ) } ` ) ;
0 commit comments