@@ -59,7 +59,7 @@ public static Helper Instance
59
59
/// </summary>
60
60
public PSCmdlet MyCmdlet { get ; set ; }
61
61
62
- private TupleComparer tupleComparer = new TupleComparer ( ) ;
62
+ internal TupleComparer tupleComparer = new TupleComparer ( ) ;
63
63
64
64
/// <summary>
65
65
/// My Tokens
@@ -605,9 +605,157 @@ public bool HasSpecialVars(string varName)
605
605
return false ;
606
606
}
607
607
608
- public RuleSuppression GetRuleSuppression ( )
608
+ /// <summary>
609
+ /// Returns a dictionary of rule suppression from the ast.
610
+ /// Key of the dictionary is rule name.
611
+ /// Value is a list of tuple of integers that represents the interval to apply the rule
612
+ /// </summary>
613
+ /// <param name="ast"></param>
614
+ /// <returns></returns>
615
+ public Dictionary < string , LinkedList < Tuple < int , int > > > GetRuleSuppression ( Ast ast )
609
616
{
610
- return null ;
617
+ List < RuleSuppression > ruleSuppressionList = new List < RuleSuppression > ( ) ;
618
+ IEnumerable < FunctionDefinitionAst > funcAsts = ast . FindAll ( item => item is FunctionDefinitionAst , true ) . Cast < FunctionDefinitionAst > ( ) ;
619
+ foreach ( var funcAst in funcAsts )
620
+ {
621
+ ruleSuppressionList . AddRange ( GetSuppressionFunction ( funcAst ) ) ;
622
+ }
623
+
624
+ Dictionary < string , LinkedList < Tuple < int , int > > > results = new Dictionary < string , LinkedList < Tuple < int , int > > > ( StringComparer . OrdinalIgnoreCase ) ;
625
+ ruleSuppressionList . Sort ( ( item , item2 ) => item . StartOffSet . CompareTo ( item2 . StartOffSet ) ) ;
626
+
627
+ foreach ( RuleSuppression ruleSuppression in ruleSuppressionList )
628
+ {
629
+ if ( ! results . ContainsKey ( ruleSuppression . RuleName ) )
630
+ {
631
+ LinkedList < Tuple < int , int > > intervals = new LinkedList < Tuple < int , int > > ( ) ;
632
+ intervals . AddLast ( Tuple . Create ( ruleSuppression . StartOffSet , ruleSuppression . EndOffset ) ) ;
633
+ results . Add ( ruleSuppression . RuleName , intervals ) ;
634
+ }
635
+ else
636
+ {
637
+ LinkedList < Tuple < int , int > > intervals = results [ ruleSuppression . RuleName ] ;
638
+ int previousEnd = intervals . Last . Value . Item2 ;
639
+
640
+ // proccess the intervals so they do not overlap and is sorted in order
641
+ if ( ruleSuppression . StartOffSet <= previousEnd )
642
+ {
643
+ if ( ruleSuppression . EndOffset <= previousEnd )
644
+ {
645
+ continue ;
646
+ }
647
+ else
648
+ {
649
+ intervals . Last . Value = Tuple . Create ( intervals . Last . Value . Item1 , ruleSuppression . EndOffset ) ;
650
+ }
651
+ }
652
+ else
653
+ {
654
+ intervals . AddLast ( Tuple . Create ( ruleSuppression . StartOffSet , ruleSuppression . EndOffset ) ) ;
655
+ }
656
+ }
657
+ }
658
+
659
+ return results ;
660
+ }
661
+
662
+ /// <summary>
663
+ /// Returns a list of rule suppressions from the function
664
+ /// </summary>
665
+ /// <param name="funcAst"></param>
666
+ /// <returns></returns>
667
+ internal List < RuleSuppression > GetSuppressionFunction ( FunctionDefinitionAst funcAst )
668
+ {
669
+ List < RuleSuppression > result = new List < RuleSuppression > ( ) ;
670
+
671
+ if ( funcAst != null && funcAst . Body != null
672
+ && funcAst . Body . ParamBlock != null && funcAst . Body . ParamBlock . Attributes != null )
673
+ {
674
+ IEnumerable < AttributeAst > suppressionAttribute = funcAst . Body . ParamBlock . Attributes . Where (
675
+ item => item . TypeName . GetReflectionType ( ) == typeof ( System . Diagnostics . CodeAnalysis . SuppressMessageAttribute ) ) ;
676
+
677
+ foreach ( var attributeAst in suppressionAttribute )
678
+ {
679
+ RuleSuppression ruleSupp = new RuleSuppression ( attributeAst , funcAst . Extent . StartOffset , funcAst . Extent . EndOffset ) ;
680
+ if ( String . IsNullOrWhiteSpace ( ruleSupp . Error ) )
681
+ {
682
+ result . Add ( ruleSupp ) ;
683
+ }
684
+ }
685
+ }
686
+
687
+ return result ;
688
+ }
689
+
690
+ /// <summary>
691
+ /// Suppress the rules from the diagnostic records list and return the result
692
+ /// </summary>
693
+ /// <param name="ruleSuppressions"></param>
694
+ /// <param name="diagnostics"></param>
695
+ public List < DiagnosticRecord > SuppressRule ( string ruleName , Dictionary < string , LinkedList < Tuple < int , int > > > ruleSuppressions , List < DiagnosticRecord > diagnostics )
696
+ {
697
+ List < DiagnosticRecord > results = new List < DiagnosticRecord > ( ) ;
698
+ if ( ! ruleSuppressions . ContainsKey ( ruleName ) || diagnostics . Count == 0 )
699
+ {
700
+ return diagnostics ;
701
+ }
702
+
703
+ LinkedList < Tuple < int , int > > intervals = ruleSuppressions [ ruleName ] ;
704
+
705
+ if ( intervals . Count == 0 )
706
+ {
707
+ return diagnostics ;
708
+ }
709
+
710
+ int recordIndex = 0 ;
711
+ DiagnosticRecord record = diagnostics . First ( ) ;
712
+ LinkedListNode < Tuple < int , int > > interval = intervals . First ;
713
+
714
+ while ( recordIndex < diagnostics . Count )
715
+ {
716
+ // the record precedes the interval so don't apply the suppression
717
+ if ( record . Extent . StartOffset < interval . Value . Item1 )
718
+ {
719
+ results . Add ( record ) ;
720
+ recordIndex += 1 ;
721
+
722
+ if ( recordIndex == diagnostics . Count )
723
+ {
724
+ break ;
725
+ }
726
+ else
727
+ {
728
+ // move on to the next record
729
+ record = diagnostics [ recordIndex ] ;
730
+ continue ;
731
+ }
732
+ }
733
+
734
+ // end of the rule suppression is less than the record start offset so move on to next interval
735
+ if ( interval . Value . Item2 < record . Extent . StartOffset )
736
+ {
737
+ interval = interval . Next ;
738
+
739
+ if ( interval == null )
740
+ {
741
+ break ;
742
+ }
743
+
744
+ continue ;
745
+ }
746
+
747
+ // here the record is inside the interval so we don't add it to the result
748
+ recordIndex += 1 ;
749
+
750
+ if ( recordIndex == diagnostics . Count )
751
+ {
752
+ break ;
753
+ }
754
+
755
+ record = diagnostics [ recordIndex ] ;
756
+ }
757
+
758
+ return results ;
611
759
}
612
760
613
761
#endregion
@@ -696,16 +844,6 @@ public object VisitScriptBlock(ScriptBlockAst scriptBlockAst)
696
844
return null ;
697
845
}
698
846
699
- /// <summary>
700
- /// Do nothing
701
- /// </summary>
702
- /// <param name="baseCtorInvokeMemberExpressionAst"></param>
703
- /// <returns></returns>
704
- public object VisitBaseCtorInvokeMemberExpression ( BaseCtorInvokeMemberExpressionAst baseCtorInvokeMemberExpressionAst )
705
- {
706
- return null ;
707
- }
708
-
709
847
/// <summary>
710
848
/// Do nothing
711
849
/// </summary>
0 commit comments