@@ -229,6 +229,141 @@ public bool IsDscResourceModule(string filePath)
229
229
return false ;
230
230
}
231
231
232
+ /// <summary>
233
+ /// Get the list of exported function by analyzing the ast
234
+ /// </summary>
235
+ /// <param name="ast"></param>
236
+ /// <returns></returns>
237
+ public HashSet < string > GetExportedFunction ( Ast ast )
238
+ {
239
+ HashSet < string > exportedFunctions = new HashSet < string > ( StringComparer . OrdinalIgnoreCase ) ;
240
+ List < string > exportFunctionsCmdlet = Helper . Instance . CmdletNameAndAliases ( "export-modulemember" ) ;
241
+
242
+ // find functions exported
243
+ IEnumerable < Ast > cmdAsts = ast . FindAll ( item => item is CommandAst
244
+ && exportFunctionsCmdlet . Contains ( ( item as CommandAst ) . GetCommandName ( ) , StringComparer . OrdinalIgnoreCase ) , true ) ;
245
+
246
+ CommandInfo exportMM = Helper . Instance . GetCommandInfo ( "export-modulemember" , CommandTypes . Cmdlet ) ;
247
+
248
+ // switch parameters
249
+ IEnumerable < ParameterMetadata > switchParams = ( exportMM != null ) ? exportMM . Parameters . Values . Where < ParameterMetadata > ( pm => pm . SwitchParameter ) : Enumerable . Empty < ParameterMetadata > ( ) ;
250
+
251
+ if ( exportMM == null )
252
+ {
253
+ return exportedFunctions ;
254
+ }
255
+
256
+ foreach ( CommandAst cmdAst in cmdAsts )
257
+ {
258
+ if ( cmdAst . CommandElements == null || cmdAst . CommandElements . Count < 2 )
259
+ {
260
+ continue ;
261
+ }
262
+
263
+ int i = 1 ;
264
+
265
+ while ( i < cmdAst . CommandElements . Count )
266
+ {
267
+ CommandElementAst ceAst = cmdAst . CommandElements [ i ] ;
268
+ ExpressionAst exprAst = null ;
269
+
270
+ if ( ceAst is CommandParameterAst )
271
+ {
272
+ var paramAst = ceAst as CommandParameterAst ;
273
+ var param = exportMM . ResolveParameter ( paramAst . ParameterName ) ;
274
+
275
+ if ( param == null )
276
+ {
277
+ i += 1 ;
278
+ continue ;
279
+ }
280
+
281
+ if ( string . Equals ( param . Name , "function" , StringComparison . OrdinalIgnoreCase ) )
282
+ {
283
+ // checks for the case of -Function:"verb-nouns"
284
+ if ( paramAst . Argument != null )
285
+ {
286
+ exprAst = paramAst . Argument ;
287
+ }
288
+ // checks for the case of -Function "verb-nouns"
289
+ else if ( i < cmdAst . CommandElements . Count - 1 )
290
+ {
291
+ i += 1 ;
292
+ exprAst = cmdAst . CommandElements [ i ] as ExpressionAst ;
293
+ }
294
+ }
295
+ // some other parameter. we just checks whether the one after this is positional
296
+ else if ( i < cmdAst . CommandElements . Count - 1 )
297
+ {
298
+ // the next element is a parameter like -module so just move to that one
299
+ if ( cmdAst . CommandElements [ i + 1 ] is CommandParameterAst )
300
+ {
301
+ i += 1 ;
302
+ continue ;
303
+ }
304
+
305
+ // not a switch parameter so the next element is definitely the argument to this parameter
306
+ if ( paramAst . Argument == null && ! switchParams . Contains ( param ) )
307
+ {
308
+ // skips the next element
309
+ i += 1 ;
310
+ }
311
+
312
+ i += 1 ;
313
+ continue ;
314
+ }
315
+ }
316
+ else if ( ceAst is ExpressionAst )
317
+ {
318
+ exprAst = ceAst as ExpressionAst ;
319
+ }
320
+
321
+ if ( exprAst != null )
322
+ {
323
+ // One string so just add this to the list
324
+ if ( exprAst is StringConstantExpressionAst )
325
+ {
326
+ exportedFunctions . Add ( ( exprAst as StringConstantExpressionAst ) . Value ) ;
327
+ }
328
+ // Array of the form "v-n", "v-n1"
329
+ else if ( exprAst is ArrayLiteralAst )
330
+ {
331
+ exportedFunctions . UnionWith ( Helper . Instance . GetStringsFromArrayLiteral ( exprAst as ArrayLiteralAst ) ) ;
332
+ }
333
+ // Array of the form @("v-n", "v-n1")
334
+ else if ( exprAst is ArrayExpressionAst )
335
+ {
336
+ ArrayExpressionAst arrExAst = exprAst as ArrayExpressionAst ;
337
+ if ( arrExAst . SubExpression != null && arrExAst . SubExpression . Statements != null )
338
+ {
339
+ foreach ( StatementAst stAst in arrExAst . SubExpression . Statements )
340
+ {
341
+ if ( stAst is PipelineAst )
342
+ {
343
+ PipelineAst pipeAst = stAst as PipelineAst ;
344
+ if ( pipeAst . PipelineElements != null )
345
+ {
346
+ foreach ( CommandBaseAst cmdBaseAst in pipeAst . PipelineElements )
347
+ {
348
+ if ( cmdBaseAst is CommandExpressionAst )
349
+ {
350
+ exportedFunctions . UnionWith ( Helper . Instance . GetStringsFromArrayLiteral ( ( cmdBaseAst as CommandExpressionAst ) . Expression as ArrayLiteralAst ) ) ;
351
+ }
352
+ }
353
+ }
354
+ }
355
+ }
356
+ }
357
+ }
358
+ }
359
+
360
+ i += 1 ;
361
+ }
362
+ }
363
+
364
+ return exportedFunctions ;
365
+ }
366
+
232
367
/// <summary>
233
368
/// Given a filePath. Returns true if it is a powershell help file
234
369
/// </summary>
0 commit comments