38
38
import org .antlr .v4 .runtime .tree .RuleNode ;
39
39
import org .antlr .v4 .runtime .tree .TerminalNode ;
40
40
import org .apache .commons .lang3 .tuple .Pair ;
41
+ import org .apache .commons .lang3 .tuple .Triple ;
41
42
import org .eclipse .lsp4j .DiagnosticRelatedInformation ;
42
43
import org .eclipse .lsp4j .Position ;
43
44
import org .eclipse .lsp4j .Range ;
60
61
61
62
@ RequiredArgsConstructor
62
63
public class RewriteMethodParameterDiagnostic extends AbstractDiagnostic {
64
+ private static final int COUNT_OF_PAIR_FOR_SELF_ASSIGN = 2 ;
63
65
private final ReferenceIndex referenceIndex ;
64
66
65
67
@ Override
@@ -70,7 +72,9 @@ public void check() {
70
72
.map (this ::isOverwrited )
71
73
.filter (Optional ::isPresent )
72
74
.map (Optional ::get )
73
- .forEach (variableSymbolListPair -> fireIssue (variableSymbolListPair .getLeft (), variableSymbolListPair .getRight ()));
75
+ .forEach (variableSymbolReferenceListTriple -> fireIssue (variableSymbolReferenceListTriple .getLeft (),
76
+ variableSymbolReferenceListTriple .getMiddle (),
77
+ variableSymbolReferenceListTriple .getRight ()));
74
78
75
79
}
76
80
@@ -89,25 +93,10 @@ private static Stream<VariableSymbol> getVariableByParameter(MethodSymbol method
89
93
.findFirst ().stream ();
90
94
}
91
95
92
- private Optional <Pair <VariableSymbol , List <Reference >>> isOverwrited (VariableSymbol variable ) {
96
+ private Optional <Triple <VariableSymbol , Reference , List <Reference >>> isOverwrited (VariableSymbol variable ) {
93
97
final var references = getSortedReferencesByLocation (variable );
94
- if (isOverwrited (references )) {
95
- return Optional .of (Pair .of (variable , references ));
96
- }
97
- return Optional .empty ();
98
- }
99
-
100
- private boolean isOverwrited (List <Reference > references ) {
101
- if (!references .isEmpty ()) {
102
- final var firstDefIntoAssign = references .get (0 );
103
- if (firstDefIntoAssign .getOccurrenceType () == OccurrenceType .DEFINITION ) {
104
- if (references .size () == 1 ) {
105
- return true ;
106
- }
107
- return noneWritingToDefOrSelfAssign (firstDefIntoAssign , references .get (1 ));
108
- }
109
- }
110
- return false ;
98
+ return isOverwrited (references )
99
+ .map (defReference -> Triple .of (variable , defReference , references ));
111
100
}
112
101
113
102
private List <Reference > getSortedReferencesByLocation (VariableSymbol variable ) {
@@ -135,7 +124,29 @@ public static int compare(Position pos1, Position pos2) {
135
124
// 1,9 1,4
136
125
}
137
126
138
- private boolean noneWritingToDefOrSelfAssign (Reference defRef , Reference nextRef ) {
127
+ private Optional <Reference > isOverwrited (List <Reference > references ) {
128
+ if (!references .isEmpty ()) {
129
+ final var firstDefIntoAssign = references .get (0 );
130
+ if (firstDefIntoAssign .getOccurrenceType () == OccurrenceType .DEFINITION ) {
131
+ if (references .size () == 1 ) {
132
+ return Optional .of (firstDefIntoAssign );
133
+ }
134
+ var refContextInsideDefAssign = getRefContextInsideDefAssign (firstDefIntoAssign , references .get (1 ));
135
+ if (refContextInsideDefAssign .isEmpty ()){
136
+ return Optional .of (firstDefIntoAssign );
137
+ }
138
+ var isSelfAssign = Boolean .TRUE .equals (refContextInsideDefAssign
139
+ .map (RewriteMethodParameterDiagnostic ::isVarNameOnlyIntoExpression )
140
+ .orElseThrow ());
141
+ if (isSelfAssign && references .size () > COUNT_OF_PAIR_FOR_SELF_ASSIGN ){
142
+ return isOverwrited (references .subList (COUNT_OF_PAIR_FOR_SELF_ASSIGN , references .size ()));
143
+ }
144
+ }
145
+ }
146
+ return Optional .empty ();
147
+ }
148
+
149
+ private Optional <RuleNode > getRefContextInsideDefAssign (Reference defRef , Reference nextRef ) {
139
150
final var defNode = Trees .findNodeContainsPosition (documentContext .getAst (),
140
151
defRef .getSelectionRange ().getStart ());
141
152
final var assignment = defNode
@@ -145,19 +156,15 @@ private boolean noneWritingToDefOrSelfAssign(Reference defRef, Reference nextRef
145
156
.filter (BSLParser .AssignmentContext .class ::isInstance )
146
157
.map (BSLParser .AssignmentContext .class ::cast );
147
158
if (assignment .isEmpty ()) {
148
- return true ;
159
+ return Optional . empty () ;
149
160
}
150
161
151
- final var refContext = Trees .findNodeContainsPosition (assignment .get (), nextRef .getSelectionRange ().getStart ())
162
+ return Trees .findNodeContainsPosition (assignment .get (), nextRef .getSelectionRange ().getStart ())
152
163
.map (TerminalNode ::getParent );
153
- if (refContext .isEmpty ()){
154
- return true ;
155
- }
156
- return isVarNameOnlyIntoExpression (refContext );
157
164
}
158
165
159
- private static boolean isVarNameOnlyIntoExpression (Optional < RuleNode > refContext ) {
160
- return refContext
166
+ private static boolean isVarNameOnlyIntoExpression (RuleNode refContext ) {
167
+ return Optional . of ( refContext )
161
168
.filter (BSLParser .ComplexIdentifierContext .class ::isInstance )
162
169
.map (BSLParser .ComplexIdentifierContext .class ::cast )
163
170
.filter (node -> node .getChildCount () == 1 )
@@ -170,7 +177,7 @@ private static boolean isVarNameOnlyIntoExpression(Optional<RuleNode> refContext
170
177
.isPresent ();
171
178
}
172
179
173
- private void fireIssue (VariableSymbol variable , List <Reference > references ) {
180
+ private void fireIssue (VariableSymbol variable , Reference nodeForIssue , List <Reference > references ) {
174
181
var refsForIssue = references .stream ()
175
182
.map (reference -> RelatedInformation .create (
176
183
documentContext .getUri (),
@@ -184,6 +191,6 @@ private void fireIssue(VariableSymbol variable, List<Reference> references) {
184
191
"0" ));
185
192
resultRefs .addAll (refsForIssue );
186
193
187
- diagnosticStorage .addDiagnostic (references . get ( 0 ) .getSelectionRange (), info .getMessage (variable .getName ()), resultRefs );
194
+ diagnosticStorage .addDiagnostic (nodeForIssue .getSelectionRange (), info .getMessage (variable .getName ()), resultRefs );
188
195
}
189
196
}
0 commit comments