@@ -150,6 +150,8 @@ public TypeInferenceContext(PowerShell powerShell)
150
150
151
151
public TypeDefinitionAst CurrentTypeDefinitionAst { get ; set ; }
152
152
153
+ public HashSet < IParameterMetadataProvider > AnalyzedCommands { get ; } = new HashSet < IParameterMetadataProvider > ( ) ;
154
+
153
155
public TypeInferenceRuntimePermissions RuntimePermissions { get ; set ; }
154
156
155
157
internal PowerShellExecutionHelper Helper { get ; }
@@ -1339,6 +1341,13 @@ private void InferTypesFrom(CommandAst commandAst, List<PSTypeName> inferredType
1339
1341
}
1340
1342
}
1341
1343
1344
+ if ( commandAst . CommandElements [ 0 ] is ScriptBlockExpressionAst scriptBlock )
1345
+ {
1346
+ // An anonymous function like: & {"Do Something"}
1347
+ inferredTypes . AddRange ( InferTypes ( scriptBlock . ScriptBlock ) ) ;
1348
+ return ;
1349
+ }
1350
+
1342
1351
PseudoBindingInfo pseudoBinding = new PseudoParameterBinder ( )
1343
1352
. DoPseudoParameterBinding ( commandAst , null , null , PseudoParameterBinder . BindingType . ParameterCompletion ) ;
1344
1353
@@ -1421,6 +1430,21 @@ private void InferTypesFrom(CommandAst commandAst, List<PSTypeName> inferredType
1421
1430
}
1422
1431
}
1423
1432
1433
+ if ( ( commandInfo . OutputType . Count == 0
1434
+ || ( commandInfo . OutputType . Count == 1
1435
+ && ( commandInfo . OutputType [ 0 ] . Name . EqualsOrdinalIgnoreCase ( typeof ( PSObject ) . FullName )
1436
+ || commandInfo . OutputType [ 0 ] . Name . EqualsOrdinalIgnoreCase ( typeof ( object ) . FullName ) ) ) )
1437
+ && commandInfo is IScriptCommandInfo scriptCommandInfo
1438
+ && scriptCommandInfo . ScriptBlock . Ast is IParameterMetadataProvider scriptBlockWithParams
1439
+ && _context . AnalyzedCommands . Add ( scriptBlockWithParams ) )
1440
+ {
1441
+ // This is a function without an output type defined (or it's too generic to be useful)
1442
+ // We can analyze the code inside the function to find out what it actually outputs
1443
+ // The purpose of the hashset is to avoid infinite loops with functions that call themselves.
1444
+ inferredTypes . AddRange ( InferTypes ( scriptBlockWithParams . Body ) ) ;
1445
+ return ;
1446
+ }
1447
+
1424
1448
// The OutputType property ignores the parameter set specified in the OutputTypeAttribute.
1425
1449
// With pseudo-binding, we actually know the candidate parameter sets, so we could take
1426
1450
// advantage of it here, but I opted for the simpler code because so few cmdlets use
0 commit comments