@@ -126,7 +126,7 @@ function DocType(type, loc) {
126126 this . valid = parsed . valid ;
127127
128128 if ( parsed . valid && parsed . variable ) {
129- this . loc . column = this . loc . column + 3 ;
129+ this . loc . column = this . loc . column + 3 ; // ' * '.length
130130 }
131131
132132 /**
@@ -137,6 +137,17 @@ function DocType(type, loc) {
137137 this . match = function ( node ) {
138138 return jsDocMatchType ( data , node ) ;
139139 } ;
140+
141+ /**
142+ * @param {function(TypeBuilder) } cb Calling for each node
143+ * @returns {Array }
144+ */
145+ this . iterate = function ( cb ) {
146+ if ( ! parsed . valid ) {
147+ return [ ] ;
148+ }
149+ return _iterateDocTypes ( parsed , cb ) ;
150+ } ;
140151}
141152
142153/**
@@ -296,6 +307,96 @@ function _parseDocType(typeString) {
296307 return node ;
297308}
298309
310+ function _iterateDocTypes ( node , cb ) {
311+ var res ;
312+
313+ switch ( true ) {
314+ case node instanceof TypeBuilder . TypeUnion :
315+ // optional: boolean,
316+ // nullable: boolean,
317+ // variable: boolean,
318+ // nonNullable: boolean,
319+ // all: boolean,
320+ // unknown: boolean,
321+ // types: Array.<TypeName|GenericType|FunctionType|RecordType>
322+ res = node . types . map ( function ( subnode ) {
323+ if ( node . selfNode ) {
324+ subnode . parentNode = node . selfNode ;
325+ }
326+ return _iterateDocTypes ( subnode , cb ) ;
327+ } ) ;
328+ break ;
329+
330+ case node instanceof TypeBuilder . TypeName :
331+ // name: string
332+ node . typeName = node . name ;
333+ res = cb ( node ) ;
334+ break ;
335+
336+ case node instanceof TypeBuilder . GenericType :
337+ // genericTypeName: string,
338+ // parameterTypeUnions: Array.<TypeUnion>
339+ node . typeName = node . genericTypeName ;
340+ res = cb ( node ) ;
341+ if ( node . parameterTypeUnions ) {
342+ node . parameterTypeUnions . selfNode = node ;
343+ res . concat ( _iterateDocTypes ( node . parameterTypeUnions , cb ) ) ;
344+ }
345+ break ;
346+
347+ case node instanceof TypeBuilder . FunctionType :
348+ // parameterTypeUnions: Array.<TypeUnion>,
349+ // returnTypeUnion: TypeUnion|null,
350+ // isConstructor: boolean,
351+ // contextTypeUnion: TypeUnion|null
352+ node . typeName = 'Function' ;
353+ res = cb ( node ) || [ ] ;
354+ res . concat ( node . parameterTypeUnions . map ( function ( subnode ) {
355+ subnode . parentNode = node ;
356+ _iterateDocTypes ( subnode , cb ) ;
357+ } ) ) ;
358+ if ( node . returnTypeUnion ) {
359+ node . returnTypeUnion . selfNode = node ;
360+ res . concat ( _iterateDocTypes ( node . returnTypeUnion , cb ) ) ;
361+ }
362+ if ( node . contextTypeUnion ) {
363+ node . contextTypeUnion . selfNode = node ;
364+ res . concat ( _iterateDocTypes ( node . contextTypeUnion , cb ) ) ;
365+ }
366+ break ;
367+
368+ case node instanceof TypeBuilder . RecordType :
369+ // entries: Array.<RecordEntry>
370+ node . typeName = 'Object' ;
371+ res = cb ( node ) || [ ] ;
372+ if ( node . entries ) {
373+ res . concat ( node . entries . map ( function ( subnode ) {
374+ subnode . parentNode = node ;
375+ _iterateDocTypes ( subnode , cb ) ;
376+ } ) ) ;
377+ }
378+ break ;
379+
380+ case node instanceof TypeBuilder . RecordType . Entry :
381+ // name: string,
382+ // typeUnion: TypeUnion
383+ node . typeUnion . selfNode = node ;
384+ res = _iterateDocTypes ( node . typeUnion , cb ) ;
385+ break ;
386+
387+ case node instanceof TypeBuilder . ModuleName :
388+ node . typeName = node . name ;
389+ node . module = true ;
390+ res = cb ( node ) ;
391+ break ;
392+
393+ default :
394+ throw new Error ( 'DocType: Unsupported doc node' ) ;
395+ }
396+
397+ return res ;
398+ }
399+
299400/**
300401 * Converts AST jsDoc node to simple object
301402 * @param {Object } node
0 commit comments