2323import au .com .integradev .delphi .cfg .api .Block ;
2424import au .com .integradev .delphi .cfg .api .ControlFlowGraph ;
2525import au .com .integradev .delphi .cfg .api .Finally ;
26- import au .com .integradev .delphi .cfg .api .Linear ;
2726import au .com .integradev .delphi .cfg .api .UnconditionalJump ;
2827import org .sonar .check .Rule ;
2928import org .sonar .plugins .communitydelphi .api .ast .AnonymousMethodNode ;
3029import org .sonar .plugins .communitydelphi .api .ast .ArgumentListNode ;
31- import org .sonar .plugins .communitydelphi .api .ast .CompoundStatementNode ;
3230import org .sonar .plugins .communitydelphi .api .ast .DelphiNode ;
3331import org .sonar .plugins .communitydelphi .api .ast .NameReferenceNode ;
3432import org .sonar .plugins .communitydelphi .api .ast .RoutineImplementationNode ;
@@ -53,12 +51,8 @@ public DelphiCheckContext visit(RoutineImplementationNode routine, DelphiCheckCo
5351
5452 @ Override
5553 public DelphiCheckContext visit (AnonymousMethodNode routine , DelphiCheckContext context ) {
56- CompoundStatementNode compoundStatementNode =
57- routine .getFirstChildOfType (CompoundStatementNode .class );
58- if (compoundStatementNode != null ) {
59- ControlFlowGraph cfg = ControlFlowGraphFactory .create (compoundStatementNode );
60- cfg .getBlocks ().forEach (block -> checkBlock (block , context ));
61- }
54+ ControlFlowGraph cfg = ControlFlowGraphFactory .create (routine .getStatementBlock ());
55+ cfg .getBlocks ().forEach (block -> checkBlock (block , context ));
6256
6357 return super .visit (routine , context );
6458 }
@@ -69,19 +63,20 @@ private void checkBlock(Block block, DelphiCheckContext context) {
6963 }
7064
7165 UnconditionalJump jump = (UnconditionalJump ) block ;
72- Block successorWithoutJump = jump .getSuccessorIfRemoved ();
7366 DelphiNode terminator = jump .getTerminator ();
7467
7568 RoutineNameDeclaration routineNameDeclaration = getRoutineNameDeclaration (terminator );
69+ if (routineNameDeclaration == null ) {
70+ return ;
71+ }
72+
7673 if (!isContinueOrExit (routineNameDeclaration )
7774 || isExitWithExpression (routineNameDeclaration , terminator )) {
7875 return ;
7976 }
8077
8178 Block successor = jump .getSuccessor ();
82- successorWithoutJump = nonEmptySuccessor (successorWithoutJump );
83-
84- if (!successorWithoutJump .equals (successor )) {
79+ if (!successor .equals (jump .getSuccessorIfRemoved ())) {
8580 return ;
8681 }
8782
@@ -116,46 +111,31 @@ private static boolean onlyFinallyBlocksBeforeEnd(Block finallyBlock) {
116111 }
117112
118113 private static RoutineNameDeclaration getRoutineNameDeclaration (DelphiNode node ) {
119- if (!(node instanceof NameReferenceNode )) {
120- return null ;
114+ NameDeclaration nameDeclaration = null ;
115+ if (node instanceof NameReferenceNode ) {
116+ nameDeclaration = ((NameReferenceNode ) node ).getNameDeclaration ();
121117 }
122- NameDeclaration nameDeclaration = ((NameReferenceNode ) node ).getNameDeclaration ();
123- if (!(nameDeclaration instanceof RoutineNameDeclaration )) {
124- return null ;
118+ if (nameDeclaration instanceof RoutineNameDeclaration ) {
119+ return (RoutineNameDeclaration ) nameDeclaration ;
125120 }
126- return ( RoutineNameDeclaration ) nameDeclaration ;
121+ return null ;
127122 }
128123
129124 private static boolean isContinueOrExit (RoutineNameDeclaration routineNameDeclaration ) {
130- if (routineNameDeclaration == null ) {
131- return false ;
132- }
133125 String fullyQualifiedName = routineNameDeclaration .fullyQualifiedName ();
134126 return fullyQualifiedName .equals ("System.Continue" ) || fullyQualifiedName .equals ("System.Exit" );
135127 }
136128
137129 private static boolean isExitWithExpression (
138130 RoutineNameDeclaration routineNameDeclaration , DelphiNode statement ) {
139- if (routineNameDeclaration == null ) {
140- return false ;
141- }
142131 String fullyQualifiedName = routineNameDeclaration .fullyQualifiedName ();
143132 if (!fullyQualifiedName .equals ("System.Exit" )) {
144133 return false ;
145134 }
146- ArgumentListNode argumentList =
147- statement .getParent ().getFirstChildOfType (ArgumentListNode .class );
148- if (argumentList == null ) {
149- return false ;
150- }
151- return argumentList .getArgumentNodes ().size () == 1 ;
152- }
153135
154- private static Block nonEmptySuccessor (Block initialBlock ) {
155- Block result = initialBlock ;
156- while (result .getElements ().isEmpty () && result instanceof Linear ) {
157- result = ((Linear ) result ).getSuccessor ();
158- }
159- return result ;
136+ var argumentList = statement .getParent ().getFirstChildOfType (ArgumentListNode .class );
137+ int arguments = argumentList == null ? 0 : argumentList .getArgumentNodes ().size ();
138+
139+ return arguments > 0 ;
160140 }
161141}
0 commit comments