@@ -569,14 +569,14 @@ private IEnumerable<DiagnosticRecord> FindParameterViolations(Ast ast)
569
569
bool isInsideString = false ;
570
570
foreach ( var stringAst in stringAsts )
571
571
{
572
- if ( stringAst . Extent . StartOffset < leftExtent . EndOffset &&
572
+ if ( stringAst . Extent . StartOffset < leftExtent . EndOffset &&
573
573
stringAst . Extent . EndOffset > rightExtent . StartOffset )
574
574
{
575
575
isInsideString = true ;
576
576
break ;
577
577
}
578
578
}
579
-
579
+
580
580
if ( isInsideString )
581
581
{
582
582
continue ;
@@ -633,7 +633,7 @@ private IEnumerable<DiagnosticRecord> FindSeparatorViolations(TokenOperations to
633
633
{
634
634
var prevTok = tokenNode . Previous . Value ;
635
635
var nextTok = tokenNode . Next . Value ;
636
-
636
+
637
637
// Skip if comma appears to be within a parameter value (no spaces around it)
638
638
if ( ( prevTok . Kind == TokenKind . Identifier || prevTok . Kind == TokenKind . Generic ) &&
639
639
( nextTok . Kind == TokenKind . Identifier || nextTok . Kind == TokenKind . Generic ) &&
@@ -766,53 +766,49 @@ private IEnumerable<DiagnosticRecord> FindOperatorViolations(TokenOperations tok
766
766
continue ;
767
767
}
768
768
769
- if ( tokenNode . Previous == null || tokenNode . Next == null || token . Kind == TokenKind . DotDot )
769
+ var skipNullOrDotDot = tokenNode . Previous == null ||
770
+ tokenNode . Next == null ||
771
+ token . Kind == TokenKind . DotDot ;
772
+
773
+ if ( skipNullOrDotDot )
770
774
{
771
775
continue ;
772
776
}
773
777
774
- // Check unary operator handling
775
- bool isUnaryInMethodCall = false ;
776
- if ( TokenTraits . HasTrait ( token . Kind , TokenFlags . UnaryOperator ) )
778
+ // Exclude assignment operator inside of multi-line hash tables if requested
779
+ if ( IgnoreAssignmentOperatorInsideHashTable && tokenNode . Value . Kind == TokenKind . Equals )
777
780
{
778
- // Only skip if it's a unary operator in a method call like $foo.bar(-$var)
779
- if ( tokenNode . Previous . Value . Kind == TokenKind . LParen &&
780
- tokenNode . Next . Value . Kind == TokenKind . Variable &&
781
- tokenNode . Previous . Previous != null )
781
+ Ast containingAst = tokenOperations . GetAstPosition ( tokenNode . Value ) ;
782
+ if ( containingAst is HashtableAst && containingAst . Extent . EndLineNumber != containingAst . Extent . StartLineNumber )
782
783
{
783
- var beforeLParen = tokenNode . Previous . Previous . Value ;
784
- isUnaryInMethodCall = beforeLParen . Kind == TokenKind . Dot ||
785
- ( beforeLParen . TokenFlags & TokenFlags . MemberName ) == TokenFlags . MemberName ;
784
+ continue ;
786
785
}
787
786
}
788
787
789
- if ( isUnaryInMethodCall )
790
- {
791
- continue ;
792
- }
788
+ var isUnaryOperator = TokenTraits . HasTrait ( token . Kind , TokenFlags . UnaryOperator ) ;
793
789
794
- // exclude assignment operator inside of multi-line hash tables if requested
795
- if ( IgnoreAssignmentOperatorInsideHashTable && tokenNode . Value . Kind == TokenKind . Equals )
790
+ // Check if we can skip Unary Method invocations or Unary Postfix invocations
791
+ // E.g., someObject.method(-$variable) or $A++, $B++
792
+ if ( isUnaryOperator )
796
793
{
797
- Ast containingAst = tokenOperations . GetAstPosition ( tokenNode . Value ) ;
798
- if ( containingAst is HashtableAst && containingAst . Extent . EndLineNumber != containingAst . Extent . StartLineNumber )
794
+ if ( IsUnaryOperatorInMethodCall ( tokenNode ) || IsUnaryPostfixOperator ( tokenNode ) )
799
795
{
800
796
continue ;
801
797
}
802
798
}
803
799
804
- // Check whitespace
800
+ // Check for 'before' and 'after' whitespaces
805
801
var hasWhitespaceBefore = IsPreviousTokenOnSameLineAndApartByWhitespace ( tokenNode ) ;
806
- var hasWhitespaceAfter = tokenNode . Next . Value . Kind == TokenKind . NewLine ||
807
- IsPreviousTokenOnSameLineAndApartByWhitespace ( tokenNode . Next ) ;
808
802
809
- // Special case: Don't require space before unary operator if preceded by LParen
810
- if ( TokenTraits . HasTrait ( token . Kind , TokenFlags . UnaryOperator ) &&
811
- tokenNode . Previous . Value . Kind == TokenKind . LParen )
803
+ if ( ! hasWhitespaceBefore && isUnaryOperator )
812
804
{
813
- hasWhitespaceBefore = true ;
805
+ // Special case: Don't require space before unary operator if preceded by LParen
806
+ hasWhitespaceBefore = IsPreviousTokenLParen ( tokenNode ) ;
814
807
}
815
808
809
+ var hasWhitespaceAfter = tokenNode . Next . Value . Kind == TokenKind . NewLine ||
810
+ IsPreviousTokenOnSameLineAndApartByWhitespace ( tokenNode . Next ) ;
811
+
816
812
if ( ! hasWhitespaceAfter || ! hasWhitespaceBefore )
817
813
{
818
814
yield return new DiagnosticRecord (
@@ -832,6 +828,46 @@ private IEnumerable<DiagnosticRecord> FindOperatorViolations(TokenOperations tok
832
828
}
833
829
}
834
830
831
+ private bool IsUnaryOperatorInMethodCall ( LinkedListNode < Token > tokenNode )
832
+ {
833
+ var prevToken = tokenNode . Previous ;
834
+
835
+ if ( prevToken == null || prevToken . Previous == null )
836
+ {
837
+ return false ;
838
+ }
839
+
840
+ if ( ! IsPreviousTokenLParen ( tokenNode ) || tokenNode . Next ? . Value . Kind != TokenKind . Variable )
841
+ {
842
+ return false ;
843
+ }
844
+
845
+ var tokenBeforeLParam = prevToken . Previous . Value ;
846
+
847
+ // Pattern: someObject.method(-$variable)
848
+ return tokenBeforeLParam . Kind == TokenKind . Dot ||
849
+ ( tokenBeforeLParam . TokenFlags & TokenFlags . MemberName ) == TokenFlags . MemberName ;
850
+ }
851
+
852
+ private bool IsUnaryPostfixOperator ( LinkedListNode < Token > tokenNode )
853
+ {
854
+ var token = tokenNode . Value ;
855
+
856
+ if ( token . Kind != TokenKind . PlusPlus && token . Kind != TokenKind . MinusMinus )
857
+ {
858
+ return false ;
859
+ }
860
+
861
+ // Postfix operators come after variables, identifiers, or closing brackets/parentheses
862
+ var prevToken = tokenNode . Previous . Value ;
863
+
864
+ return prevToken . Kind == TokenKind . Variable ||
865
+ prevToken . Kind == TokenKind . Identifier ||
866
+ prevToken . Kind == TokenKind . RBracket || // for array access like $arr[0]++
867
+ prevToken . Kind == TokenKind . RParen || // for expressions like ($x)++
868
+ ( prevToken . TokenFlags & TokenFlags . MemberName ) == TokenFlags . MemberName ;
869
+ }
870
+
835
871
private List < CorrectionExtent > GetCorrections (
836
872
Token prevToken ,
837
873
Token token ,
0 commit comments