@@ -712,22 +712,30 @@ public IScriptExtent GetScriptExtentForFunctionName(FunctionDefinitionAst functi
712
712
if ( null == functionDefinitionAst )
713
713
{
714
714
return null ;
715
- }
716
-
717
- // Obtain the index where the function name is in Tokens
718
- int funcTokenIndex = Tokens . Select ( ( s , index ) => new { s , index } )
719
- . Where ( x => x . s . Extent . StartOffset == functionDefinitionAst . Extent . StartOffset )
720
- . Select ( x => x . index ) . FirstOrDefault ( ) ;
715
+ }
716
+ var funcNameTokens = Tokens . Where (
717
+ token =>
718
+ ContainsExtent ( functionDefinitionAst . Extent , token . Extent )
719
+ && token . Text . Equals ( functionDefinitionAst . Name ) ) ;
720
+ var funcNameToken = funcNameTokens . FirstOrDefault ( ) ;
721
+ return funcNameToken == null ? null : funcNameToken . Extent ;
722
+ }
721
723
722
- if ( funcTokenIndex > 0 && funcTokenIndex < Helper . Instance . Tokens . Count ( ) )
724
+ /// <summary>
725
+ /// Return true if subset is contained in set
726
+ /// </summary>
727
+ /// <param name="set"></param>
728
+ /// <param name="subset"></param>
729
+ /// <returns>True or False</returns>
730
+ private bool ContainsExtent ( IScriptExtent set , IScriptExtent subset )
731
+ {
732
+ if ( set == null || subset == null )
723
733
{
724
- // return the extent of the next token - this is the extent for the function name
725
- return Tokens [ ++ funcTokenIndex ] . Extent ;
734
+ return false ;
726
735
}
727
-
728
- return null ;
736
+ return set . StartOffset <= subset . StartOffset
737
+ && set . EndOffset >= subset . EndOffset ;
729
738
}
730
-
731
739
private void FindClosingParenthesis ( string keyword )
732
740
{
733
741
if ( Tokens == null || Tokens . Length == 0 )
@@ -1246,12 +1254,16 @@ internal List<RuleSuppression> GetSuppressionsClass(TypeDefinitionAst typeAst)
1246
1254
/// </summary>
1247
1255
/// <param name="ruleSuppressions"></param>
1248
1256
/// <param name="diagnostics"></param>
1249
- public Tuple < List < SuppressedRecord > , List < DiagnosticRecord > > SuppressRule ( string ruleName , Dictionary < string , List < RuleSuppression > > ruleSuppressionsDict , List < DiagnosticRecord > diagnostics )
1257
+ public Tuple < List < SuppressedRecord > , List < DiagnosticRecord > > SuppressRule (
1258
+ string ruleName ,
1259
+ Dictionary < string , List < RuleSuppression > > ruleSuppressionsDict ,
1260
+ List < DiagnosticRecord > diagnostics ,
1261
+ out List < ErrorRecord > errorRecords )
1250
1262
{
1251
1263
List < SuppressedRecord > suppressedRecords = new List < SuppressedRecord > ( ) ;
1252
1264
List < DiagnosticRecord > unSuppressedRecords = new List < DiagnosticRecord > ( ) ;
1253
1265
Tuple < List < SuppressedRecord > , List < DiagnosticRecord > > result = Tuple . Create ( suppressedRecords , unSuppressedRecords ) ;
1254
-
1266
+ errorRecords = new List < ErrorRecord > ( ) ;
1255
1267
if ( diagnostics == null || diagnostics . Count == 0 )
1256
1268
{
1257
1269
return result ;
@@ -1317,8 +1329,8 @@ public Tuple<List<SuppressedRecord>, List<DiagnosticRecord>> SuppressRule(string
1317
1329
ruleSuppression . Error = String . Format ( CultureInfo . CurrentCulture , Strings . RuleSuppressionErrorFormat , ruleSuppression . StartAttributeLine ,
1318
1330
System . IO . Path . GetFileName ( diagnostics . First ( ) . Extent . File ) , String . Format ( Strings . RuleSuppressionIDError , ruleSuppression . RuleSuppressionID ) ) ;
1319
1331
}
1320
-
1321
- this . outputWriter . WriteError ( new ErrorRecord ( new ArgumentException ( ruleSuppression . Error ) , ruleSuppression . Error , ErrorCategory . InvalidArgument , ruleSuppression ) ) ;
1332
+ errorRecords . Add ( new ErrorRecord ( new ArgumentException ( ruleSuppression . Error ) , ruleSuppression . Error , ErrorCategory . InvalidArgument , ruleSuppression ) ) ;
1333
+ // this.outputWriter.WriteError(new ErrorRecord(new ArgumentException(ruleSuppression.Error), ruleSuppression.Error, ErrorCategory.InvalidArgument, ruleSuppression));
1322
1334
}
1323
1335
}
1324
1336
@@ -1372,6 +1384,135 @@ public static string[] ProcessCustomRulePaths(string[] rulePaths, SessionState s
1372
1384
return outPaths . ToArray ( ) ;
1373
1385
1374
1386
}
1387
+
1388
+ /// <summary>
1389
+ /// Check if the function name starts with one of potentailly state changing verbs
1390
+ /// </summary>
1391
+ /// <param name="functionName"></param>
1392
+ /// <returns>true if the function name starts with a state changing verb, otherwise false</returns>
1393
+ public bool IsStateChangingFunctionName ( string functionName )
1394
+ {
1395
+ if ( functionName == null )
1396
+ {
1397
+ throw new ArgumentNullException ( "functionName" ) ;
1398
+ }
1399
+ // Array of verbs that can potentially change the state of a system
1400
+ string [ ] stateChangingVerbs =
1401
+ {
1402
+ "Restart-" ,
1403
+ "Stop-" ,
1404
+ "New-" ,
1405
+ "Set-" ,
1406
+ "Update-" ,
1407
+ "Reset-" ,
1408
+ "Remove-"
1409
+ } ;
1410
+ foreach ( var verb in stateChangingVerbs )
1411
+ {
1412
+ if ( functionName . StartsWith ( verb , StringComparison . OrdinalIgnoreCase ) )
1413
+ {
1414
+ return true ;
1415
+ }
1416
+ }
1417
+ return false ;
1418
+ }
1419
+
1420
+ /// <summary>
1421
+ /// Get the SupportShouldProcess attribute ast
1422
+ /// </summary>
1423
+ /// <param name="attributeAsts"></param>
1424
+ /// <returns>Returns SupportShouldProcess attribute ast if it exists, otherwise returns null</returns>
1425
+ public NamedAttributeArgumentAst GetShouldProcessAttributeAst ( IEnumerable < AttributeAst > attributeAsts )
1426
+ {
1427
+ if ( attributeAsts == null )
1428
+ {
1429
+ throw new ArgumentNullException ( "attributeAsts" ) ;
1430
+ }
1431
+ var cmdletBindingAttributeAst = this . GetCmdletBindingAttributeAst ( attributeAsts ) ;
1432
+ if ( cmdletBindingAttributeAst == null
1433
+ || cmdletBindingAttributeAst . NamedArguments == null )
1434
+ {
1435
+ return null ;
1436
+ }
1437
+ foreach ( var namedAttributeAst in cmdletBindingAttributeAst . NamedArguments )
1438
+ {
1439
+ if ( namedAttributeAst != null
1440
+ && namedAttributeAst . ArgumentName . Equals (
1441
+ "SupportsShouldProcess" ,
1442
+ StringComparison . OrdinalIgnoreCase ) )
1443
+ {
1444
+ return namedAttributeAst ;
1445
+ }
1446
+ }
1447
+ return null ;
1448
+ }
1449
+
1450
+ /// <summary>
1451
+ /// Get the CmdletBinding attribute ast
1452
+ /// </summary>
1453
+ /// <param name="attributeAsts"></param>
1454
+ /// <returns>Returns CmdletBinding attribute ast if it exists, otherwise returns null</returns>
1455
+ public AttributeAst GetCmdletBindingAttributeAst ( IEnumerable < AttributeAst > attributeAsts )
1456
+ {
1457
+ if ( attributeAsts == null )
1458
+ {
1459
+ throw new ArgumentNullException ( "attributeAsts" ) ;
1460
+ }
1461
+ foreach ( var attributeAst in attributeAsts )
1462
+ {
1463
+ if ( attributeAst == null || attributeAst . NamedArguments == null )
1464
+ {
1465
+ continue ;
1466
+ }
1467
+ if ( attributeAst . TypeName . GetReflectionAttributeType ( )
1468
+ == typeof ( CmdletBindingAttribute ) )
1469
+ {
1470
+ return attributeAst ;
1471
+ }
1472
+ }
1473
+ return null ;
1474
+ }
1475
+
1476
+ /// <summary>
1477
+ /// Get the boolean value of the named attribute argument
1478
+ /// </summary>
1479
+ /// <param name="namedAttributeArgumentAst"></param>
1480
+ /// <returns>Boolean value of the named attribute argument</returns>
1481
+ public bool GetNamedArgumentAttributeValue ( NamedAttributeArgumentAst namedAttributeArgumentAst )
1482
+ {
1483
+ if ( namedAttributeArgumentAst == null )
1484
+ {
1485
+ throw new ArgumentNullException ( "namedAttributeArgumentAst" ) ;
1486
+ }
1487
+ if ( namedAttributeArgumentAst . ExpressionOmitted )
1488
+ {
1489
+ return true ;
1490
+ }
1491
+ else
1492
+ {
1493
+ var varExpAst = namedAttributeArgumentAst . Argument as VariableExpressionAst ;
1494
+ if ( varExpAst == null )
1495
+ {
1496
+ var constExpAst = namedAttributeArgumentAst . Argument as ConstantExpressionAst ;
1497
+ if ( constExpAst == null )
1498
+ {
1499
+ return false ;
1500
+ }
1501
+ bool constExpVal ;
1502
+ if ( LanguagePrimitives . TryConvertTo < bool > ( constExpAst . Value , out constExpVal ) )
1503
+ {
1504
+ return constExpVal ;
1505
+ }
1506
+ }
1507
+ else
1508
+ {
1509
+ return varExpAst . VariablePath . UserPath . Equals (
1510
+ bool . TrueString ,
1511
+ StringComparison . OrdinalIgnoreCase ) ;
1512
+ }
1513
+ }
1514
+ return false ;
1515
+ }
1375
1516
1376
1517
#endregion Methods
1377
1518
}
0 commit comments