@@ -12,6 +12,8 @@ public class ComparisonOperatorRule extends RuleForTokens {
12
12
new RuleReference (RuleSource .ABAP_CLEANER ) };
13
13
14
14
private final static String [] textualComparisonOps = new String [] { "LT" , "LE" , "EQ" , "NE" , "GE" , "GT" };
15
+ private final static String [] symbolicComparisonOps = new String [] { "<" , "<=" , "=" , "<>" , ">=" , ">" };
16
+ private final static String [] obsoleteComparisonOps = new String [] { "><" , "=<" , "=>" };
15
17
16
18
@ Override
17
19
public RuleID getID () { return RuleID .COMPARISON_OPERATOR ; }
@@ -20,10 +22,10 @@ public class ComparisonOperatorRule extends RuleForTokens {
20
22
public RuleGroupID getGroupID () { return RuleGroupID .SYNTAX ; }
21
23
22
24
@ Override
23
- public String getDisplayName () { return "Prefer =, <>, <= etc. to EQ, NE, LE etc. " ; }
25
+ public String getDisplayName () { return "Use consistent set of comparison operators " ; }
24
26
25
27
@ Override
26
- public String getDescription () { return "Replaces keywords (LT, LE, EQ, NE, GT, GE ) with symbolic comparison operators (<, <=, =, >= , >, <>) ." ; }
28
+ public String getDescription () { return "Replaces textual comparison operators (LT, LE, EQ, NE, GE, GT ) with symbolic comparison operators (<, <=, =, <> , >=, >) or vice versa ." ; }
27
29
28
30
@ Override
29
31
public LocalDate getDateCreated () { return LocalDate .of (2021 , 1 , 17 ); }
@@ -32,23 +34,41 @@ public class ComparisonOperatorRule extends RuleForTokens {
32
34
public RuleReference [] getReferences () { return references ; }
33
35
34
36
@ Override
35
- public RuleID [] getDependentRules () { return new RuleID [] { RuleID .ALIGN_LOGICAL_EXPRESSIONS } ; }
37
+ public RuleID [] getDependentRules () { return new RuleID [] { RuleID .UPPER_AND_LOWER_CASE , RuleID . ALIGN_LOGICAL_EXPRESSIONS } ; }
36
38
37
39
@ Override
38
40
public String getExample () {
39
41
return ""
40
- + LINE_SEP + " METHOD prefer_symbolic_comparison_ops."
42
+ + LINE_SEP + "CLASS any_class IMPLEMENTATION."
43
+ + LINE_SEP + " METHOD use_consistent_comparison_ops."
41
44
+ LINE_SEP + " IF a EQ b OR c NE d."
42
- + LINE_SEP + " IF a LT c AND b GT d"
43
- + LINE_SEP + " AND b LT e."
45
+ + LINE_SEP + " IF a < c AND b > d"
46
+ + LINE_SEP + " AND b < e."
44
47
+ LINE_SEP + " IF a LE d AND c GE b."
45
- + LINE_SEP + " \" do something "
48
+ + LINE_SEP + " result = xsdbool( a <= d OR a GE b ). "
46
49
+ LINE_SEP + " ENDIF."
47
50
+ LINE_SEP + " ENDIF."
48
51
+ LINE_SEP + " ENDIF."
49
- + LINE_SEP + " ENDMETHOD." ;
52
+ + LINE_SEP + " ENDMETHOD."
53
+ + LINE_SEP + "ENDCLASS."
54
+ + LINE_SEP
55
+ + LINE_SEP + "FORM any_form."
56
+ + LINE_SEP + " \" these obsolete variants are only possible outside of the object-oriented context:"
57
+ + LINE_SEP + " IF a >< b AND b => c OR c =< d."
58
+ + LINE_SEP + " RETURN."
59
+ + LINE_SEP + " ENDIF."
60
+ + LINE_SEP + "ENDFORM." ;
50
61
}
51
62
63
+ final ConfigEnumValue <ComparisonOperatorType > configPreferredOperatorSet = new ConfigEnumValue <ComparisonOperatorType >(this , "PreferredOperatorSet" , "Preferred set of comparison operators:" , new String [] { "symbolic (<, <=, =, <>, >=, >)" , "textual (LT, LE, EQ, NE, GE, GT)" }, ComparisonOperatorType .values (), ComparisonOperatorType .SYMBOLIC , ComparisonOperatorType .SYMBOLIC , LocalDate .of (2024 , 4 , 12 ));
64
+ final ConfigBoolValue configReplaceRegularOperators = new ConfigBoolValue (this , "ReplaceRegularOperators" , "Replace regular comparison operators with preferred variant" , true );
65
+ final ConfigBoolValue configReplaceObsoleteOperators = new ConfigBoolValue (this , "ReplaceObsoleteOperators" , "Replace obsolete comparison operators (>< => =<) with preferred variant" , true , false , LocalDate .of (2024 , 4 , 12 ));
66
+
67
+ private final ConfigValue [] configValues = new ConfigValue [] { configPreferredOperatorSet , configReplaceRegularOperators , configReplaceObsoleteOperators };
68
+
69
+ @ Override
70
+ public ConfigValue [] getConfigValues () { return configValues ; }
71
+
52
72
public ComparisonOperatorRule (Profile profile ) {
53
73
super (profile );
54
74
initializeConfiguration ();
@@ -62,7 +82,7 @@ protected boolean skipCommand(Command command) {
62
82
63
83
@ Override
64
84
protected boolean executeOn (Code code , Command command , Token token , int releaseRestriction ) {
65
- if (!token .isComparisonOperator () || ! token . isAnyComparisonOperator ( textualComparisonOps ) )
85
+ if (!token .isComparisonOperator ())
66
86
return false ;
67
87
68
88
// do NOT change 'opt' in: 'SELECT-OPTIONS selcrit FOR dobj DEFAULT val1 [TO val2] [OPTION opt] ....'
@@ -73,7 +93,24 @@ protected boolean executeOn(Code code, Command command, Token token, int release
73
93
}
74
94
}
75
95
76
- String newOperator = ABAP .getSymbolicComparisonOperator (token .getText ());
96
+ ComparisonOperatorType targetType = ComparisonOperatorType .forValue (configPreferredOperatorSet .getValue ());
97
+ String newOperator ;
98
+ if (configReplaceObsoleteOperators .getValue () && token .isAnyComparisonOperator (obsoleteComparisonOps ) && !command .isInOOContext ()) {
99
+ newOperator = ABAP .getNonObsoleteComparisonOperator (token .getText ());
100
+ if (targetType == ComparisonOperatorType .TEXTUAL ) {
101
+ newOperator = ABAP .getTextualComparisonOperator (newOperator );
102
+ }
103
+
104
+ } else if (targetType == ComparisonOperatorType .SYMBOLIC && configReplaceRegularOperators .getValue () && token .isAnyComparisonOperator (textualComparisonOps )) {
105
+ newOperator = ABAP .getSymbolicComparisonOperator (token .getText ());
106
+
107
+ } else if (targetType == ComparisonOperatorType .TEXTUAL && configReplaceRegularOperators .getValue () && token .isAnyComparisonOperator (symbolicComparisonOps )) {
108
+ newOperator = ABAP .getTextualComparisonOperator (token .getText ());
109
+
110
+ } else {
111
+ return false ;
112
+ }
113
+
77
114
token .setText (newOperator , true );
78
115
return true ;
79
116
}
0 commit comments