@@ -2915,53 +2915,20 @@ exports.handlers = {
2915
2915
currentSource = e . source ;
2916
2916
} ,
2917
2917
2918
+ /**
2919
+ * Event `parseComplete` is fired by JSDoc after all files have been parsed,
2920
+ * but before inheritance, mixins or borrows are processed.
2921
+ *
2922
+ * We use this event to merge our additional data into the doclets collected by JSDoc.
2923
+ * The merge must happen before doclets are cloned during the prcessing of augments or borrows.
2924
+ */
2918
2925
parseComplete : function ( e ) {
2919
-
2920
2926
const doclets = e . doclets ;
2921
- const rAnonymous = / ^ < a n o n y m o u s > ( ~ | $ ) / ;
2922
-
2923
- // remove undocumented symbols, ignored symbols, anonymous functions and their members, scope members
2924
- let l = doclets . length , i , j ;
2925
- for ( i = 0 , j = 0 ; i < l ; i ++ ) {
2926
-
2927
+ const l = doclets . length ;
2928
+ for ( let i = 0 ; i < l ; i ++ ) {
2927
2929
const doclet = doclets [ i ] ;
2928
- if ( ! doclet . undocumented &&
2929
- ! doclet . ignore &&
2930
- ! ( doclet . memberof && rAnonymous . test ( doclet . memberof ) ) &&
2931
- doclet . longname . indexOf ( "~" ) < 0 ) {
2932
- doclets [ j ++ ] = doclet ;
2933
- }
2934
- }
2935
- if ( j < l ) {
2936
- doclets . splice ( j , l - j ) ;
2937
- info ( `removed ${ l - j } undocumented, ignored or anonymous symbols` ) ;
2938
- l = j ;
2939
- }
2940
2930
2941
- // sort doclets by name, synthetic, lineno, uid
2942
- // 'ignore' is a combination of criteria, see function above
2943
- debug ( "sorting doclets by name" ) ;
2944
- doclets . sort ( ( a , b ) => {
2945
- if ( a . longname === b . longname ) {
2946
- if ( a . synthetic === b . synthetic ) {
2947
- if ( a . meta && b . meta && a . meta . filename == b . meta . filename ) {
2948
- if ( a . meta . lineno !== b . meta . lineno ) {
2949
- return a . meta . lineno < b . meta . lineno ? - 1 : 1 ;
2950
- }
2951
- }
2952
- return a . __ui5 . id - b . __ui5 . id ;
2953
- }
2954
- return a . synthetic && ! b . synthetic ? - 1 : 1 ;
2955
- }
2956
- return a . longname < b . longname ? - 1 : 1 ;
2957
- } ) ;
2958
- debug ( "sorting doclets by name done." ) ;
2959
-
2960
- for ( i = 0 , j = 0 ; i < l ; i ++ ) {
2961
-
2962
- const doclet = doclets [ i ] ;
2963
-
2964
- // add metadata to symbol
2931
+ // add metadata to class symbols
2965
2932
if ( classInfos [ doclet . longname ] ) {
2966
2933
// debug("class data", doclet.longname, "'" + classInfos[doclet.longname].export + "'");
2967
2934
if ( doclet . __ui5 . export === undefined ) {
@@ -3005,6 +2972,7 @@ exports.handlers = {
3005
2972
}
3006
2973
}
3007
2974
2975
+ // add DataType info to typedef symbols
3008
2976
if ( typeInfos [ doclet . longname ] ) {
3009
2977
doclet . __ui5 . stereotype = 'datatype' ;
3010
2978
doclet . __ui5 . metadata = {
@@ -3014,6 +2982,7 @@ exports.handlers = {
3014
2982
} ;
3015
2983
}
3016
2984
2985
+ // add enum values to enum keys (for enum symbols)
3017
2986
if ( ( doclet . kind === 'member' || doclet . kind === 'constant' ) && doclet . isEnum && Array . isArray ( doclet . properties ) ) {
3018
2987
// determine unique enum identifier from key set
3019
2988
let enumID = doclet . properties . map ( function ( prop ) {
@@ -3036,31 +3005,96 @@ exports.handlers = {
3036
3005
}
3037
3006
}
3038
3007
}
3008
+ }
3009
+ } ,
3010
+
3011
+ /**
3012
+ * Event `processingComplete` is fired by JSDoc after all files have been parsed,
3013
+ * and after inheritance, mixins and borrows have been processed.
3014
+ *
3015
+ * The `e.doclets` contains the symbols that will be given to templates for publishing.
3016
+ *
3017
+ * We use this event to remove symbols that are not of interest:
3018
+ * - undocumented When JSDoc finds a class, function, object or member without a
3019
+ * JSDoc comment, it creates a doclet with a truthy `undocumented`
3020
+ * property
3021
+ * - ignore A symbol that has been marked with `@ignore` in the source code
3022
+ * - anonymous JSDoc could not infer a name for the symbol, neither from source
3023
+ * code nor from JSDoc comments
3024
+ * - local Local entities (e.g. local vars) can't be addressed from the outside
3025
+ * and therefore are generally not considered as API in UI5
3026
+ * - duplicates This plugin generates doclets for the accessor methods of
3027
+ * managed properties, aggregations, events, associations.
3028
+ * Developers might have created JSDoc comments for the same methods,
3029
+ * either because they have overridden them in code or because they
3030
+ * wanted to detail the method contract. If such duplicate doclets
3031
+ * are detected, the developer created doclets are preferred. If
3032
+ * multiple developer created doclets for the same entity exist in the
3033
+ * same file, the last one wins. If multiple doclets exists across
3034
+ * files, the one created last wins (but usually, this indicates a
3035
+ * copy & paste error)
3036
+ *
3037
+ * The cleanup is done in `processingComplete` as the processing of `@augments` or
3038
+ * `@borrows` tags might have created new non-interesting symbols.
3039
+ */
3040
+ processingComplete ( e ) {
3041
+ const doclets = e . doclets ;
3042
+
3043
+ // sort doclets by name, synthetic, lineno, uid for easier detection of duplicates
3044
+ debug ( "sorting doclets by name" ) ;
3045
+ doclets . sort ( ( a , b ) => {
3046
+ if ( a . longname === b . longname ) {
3047
+ if ( a . synthetic === b . synthetic ) {
3048
+ if ( a . meta && b . meta && a . meta . filename == b . meta . filename ) {
3049
+ if ( a . meta . lineno !== b . meta . lineno ) {
3050
+ return a . meta . lineno < b . meta . lineno ? - 1 : 1 ;
3051
+ }
3052
+ }
3053
+ return a . __ui5 . id - b . __ui5 . id ;
3054
+ }
3055
+ return a . synthetic && ! b . synthetic ? - 1 : 1 ;
3056
+ }
3057
+ return a . longname < b . longname ? - 1 : 1 ;
3058
+ } ) ;
3059
+ debug ( "sorting doclets by name done." ) ;
3060
+
3061
+ // cleanup doclets
3062
+ const rAnonymous = / ^ < a n o n y m o u s > ( ~ | $ ) / ;
3063
+ const l = doclets . length ;
3064
+ let j = 0 ;
3065
+ for ( let i = 0 ; i < l ; i ++ ) {
3066
+ const doclet = doclets [ i ] ;
3067
+
3068
+ // skip undocumented, ignored, anonymous entities as well as local entities
3069
+ if ( doclet . undocumented
3070
+ || doclet . ignore
3071
+ || ( doclet . memberof && rAnonymous . test ( doclet . memberof ) )
3072
+ || doclet . longname . includes ( "~" ) ) {
3073
+ continue ;
3074
+ }
3039
3075
3040
3076
// check for duplicates: last one wins
3041
3077
if ( j > 0 && doclets [ j - 1 ] . longname === doclet . longname ) {
3042
3078
if ( ! doclets [ j - 1 ] . synthetic && ! doclet . __ui5 . updatedDoclet ) {
3043
- // replacing synthetic comments or updating comments are trivial case . Just log non-trivial duplicates
3079
+ // replacing synthetic comments or updating comments are trivial cases . Just log non-trivial duplicates
3044
3080
debug ( `ignoring duplicate doclet for ${ doclet . longname } : ${ location ( doclet ) } overrides ${ location ( doclets [ j - 1 ] ) } ` ) ;
3045
3081
}
3046
3082
doclets [ j - 1 ] = doclet ;
3047
- } else {
3048
- doclets [ j ++ ] = doclet ;
3083
+ continue ;
3049
3084
}
3085
+
3086
+ doclets [ j ++ ] = doclet ;
3050
3087
}
3051
3088
3052
3089
if ( j < l ) {
3053
3090
doclets . splice ( j , l - j ) ;
3054
- info ( `removed ${ l - j } duplicate symbols - ${ doclets . length } remaining` ) ;
3091
+ info ( `processingComplete: removed ${ l - j } undocumented, ignored, anonymous, local or duplicate symbols - ${ doclets . length } remaining` ) ;
3055
3092
}
3056
3093
3057
3094
if ( pluginConfig . saveSymbols ) {
3058
-
3059
3095
fs . mkPath ( env . opts . destination ) ;
3060
- fs . writeFileSync ( path . join ( env . opts . destination , "symbols-parseComplete.json" ) , JSON . stringify ( e . doclets , null , "\t" ) , 'utf8' ) ;
3061
-
3096
+ fs . writeFileSync ( path . join ( env . opts . destination , "symbols-processingComplete.json" ) , JSON . stringify ( e . doclets , null , "\t" ) , 'utf8' ) ;
3062
3097
}
3063
-
3064
3098
}
3065
3099
} ;
3066
3100
0 commit comments