14
14
*/
15
15
package org .eclipse .lsp .cobol .core .visitor ;
16
16
17
+ import lombok .*;
17
18
import org .eclipse .lsp .cobol .core .CobolParser .*;
18
19
import org .eclipse .lsp .cobol .core .messages .MessageService ;
19
20
import org .eclipse .lsp .cobol .core .model .ErrorSeverity ;
23
24
import org .eclipse .lsp .cobol .core .model .variables .*;
24
25
import org .eclipse .lsp .cobol .core .semantics .outline .OutlineNodeNames ;
25
26
import com .google .common .collect .ImmutableList ;
26
- import lombok .Builder ;
27
- import lombok .Data ;
28
- import lombok .NonNull ;
29
- import lombok .RequiredArgsConstructor ;
30
27
import lombok .extern .slf4j .Slf4j ;
31
28
import org .antlr .v4 .runtime .ParserRuleContext ;
32
29
import org .antlr .v4 .runtime .RuleContext ;
@@ -83,6 +80,8 @@ public class VariableDefinitionDelegate {
83
80
private final Map <Token , Locality > positions ;
84
81
private final MessageService messages ;
85
82
83
+ private final Map <String , String > redefinedVariables = new HashMap <>();
84
+
86
85
/**
87
86
* Create and accumulate a variable of level 01-49 out of the given context. Add errors if the
88
87
* variable definition contains is invalid
@@ -115,6 +114,7 @@ public void defineVariable(@NonNull DataDescriptionEntryFormat1Context ctx) {
115
114
.occursClauses (ctx .dataOccursClause ())
116
115
.valueClauses (ctx .dataValueClause ())
117
116
.usageClauses (ctx .dataUsageClause ())
117
+ .redefinesClauses (ctx .dataRedefinesClause ())
118
118
.build ();
119
119
120
120
// TODO: Add check that name does not present in the predefined variables list (? - to check)
@@ -128,6 +128,8 @@ public void defineVariable(@NonNull DataDescriptionEntryFormat1Context ctx) {
128
128
checkGlobalFlagFor01Level (variableDefinitionContext );
129
129
setValueClauseText (variableDefinitionContext );
130
130
saveGlobalVariable (variableDefinitionContext );
131
+ checkRedefinesContainsValue (variableDefinitionContext );
132
+ checkRedefinesClauseIsSingle (variableDefinitionContext );
131
133
// TODO: check the same way that the other clauses are singular or absent
132
134
133
135
defineVariable (
@@ -264,6 +266,43 @@ public ResultWithErrors<Collection<Variable>> finishDefinitionAnalysis() {
264
266
return new ResultWithErrors <>(new ArrayList <>(variables ), new ArrayList <>(errors ));
265
267
}
266
268
269
+ /**
270
+ * Handle and process REDEFINES clause
271
+ * @param context is a ParserRuleContext context
272
+ */
273
+ public void handleRedefine (DataRedefinesClauseContext context ) {
274
+ String redefinesName = VisitorHelper .getName (context .dataName ());
275
+ Locality locality = positions .get (context .dataName ().getStart ());
276
+ if (locality == null ) {
277
+ return ;
278
+ }
279
+
280
+ boolean notFound = true ;
281
+ Iterator <Variable > iterator = variables .iterator ();
282
+ if (iterator .hasNext ()) {
283
+ Variable currentVariable = iterator .next ();
284
+
285
+ while (iterator .hasNext ()) {
286
+ Variable variable = iterator .next ();
287
+ if (redefinesName .equals (variable .getName ())) {
288
+ if (currentVariable .getLevelNumber () != variable .getLevelNumber ()) {
289
+ addError (messages .getMessage ("semantics.levelsMustMatch" , redefinesName ), positions .get (context .getParent ().getStart ()));
290
+ }
291
+ notFound = false ;
292
+ break ;
293
+ } else {
294
+ if (variable .getLevelNumber () == currentVariable .getLevelNumber ()
295
+ && !redefinesName .equals (redefinedVariables .get (variable .getName ()))) {
296
+ break ;
297
+ }
298
+ }
299
+ }
300
+ if (notFound ) {
301
+ addError (messages .getMessage ("semantics.redefineImmediatelyFollow" , redefinesName ), locality );
302
+ }
303
+ }
304
+ }
305
+
267
306
private String retrieveName (RuleContext context ) {
268
307
return ofNullable (context )
269
308
.map (RuleContext ::getText )
@@ -345,6 +384,13 @@ private void addError(String suggestion, Locality locality, ErrorSeverity severi
345
384
format ("Syntax error defined by %s: %s" , getClass ().getSimpleName (), error .toString ()));
346
385
}
347
386
387
+ private void checkRedefinesContainsValue (VariableDefinitionContext variable ) {
388
+ if (!(variable .getRedefinesClauses ().isEmpty () || variable .getValueClauses ().isEmpty ())) {
389
+ Locality valueLocality = positions .get (variable .getValueClauses ().get (0 ).getStart ());
390
+ addError (messages .getMessage ("semantics.redefinedContainValue" , variable .getName ()), valueLocality );
391
+ }
392
+ }
393
+
348
394
private void checkStartingArea (VariableDefinitionContext variable ) {
349
395
if ((variable .getNumber () == LEVEL_01 || variable .getNumber () == LEVEL_77 )
350
396
&& variable .getStarting ().getRange ().getStart ().getCharacter () > AREA_A_FINISH ) {
@@ -382,6 +428,10 @@ private void checkValueClauseIsSingle(VariableDefinitionContext variable) {
382
428
checkClauseIsSingle (variable .getDefinition (), variable .getValueClauses (), "VALUE" );
383
429
}
384
430
431
+ private void checkRedefinesClauseIsSingle (VariableDefinitionContext variable ) {
432
+ checkClauseIsSingle (variable .getDefinition (), variable .getRedefinesClauses (), "REDEFINES" );
433
+ }
434
+
385
435
private void checkUsageClauseIsSingle (VariableDefinitionContext variable ) {
386
436
checkClauseIsSingle (variable .getDefinition (), variable .getUsageClauses (), "USAGE" );
387
437
}
@@ -436,6 +486,11 @@ private void defineVariable(
436
486
}
437
487
variables .push (variable );
438
488
});
489
+ Optional .ofNullable (variableDefinitionContext .getRedefinesClauses ())
490
+ .filter (l -> !l .isEmpty ())
491
+ .ifPresent (b ->
492
+ redefinedVariables .put (variableDefinitionContext .getName (),
493
+ VisitorHelper .getName (variableDefinitionContext .getRedefinesClauses ().get (0 ).dataName ())));
439
494
}
440
495
441
496
private Variable multiTableDataNameMatcher (VariableDefinitionContext variable ) {
@@ -655,6 +710,7 @@ private static class VariableDefinitionContext {
655
710
List <DataOccursClauseContext > occursClauses ;
656
711
List <DataValueClauseContext > valueClauses ;
657
712
List <DataUsageClauseContext > usageClauses ;
713
+ List <DataRedefinesClauseContext > redefinesClauses ;
658
714
String valueClauseTest ;
659
715
String thruValue ;
660
716
Variable container ;
0 commit comments