Skip to content

Commit 4d2ae8b

Browse files
committed
fix: Maintain string length while replacing #974
Signed-off-by: ap891843 <[email protected]>
1 parent 79141f5 commit 4d2ae8b

File tree

5 files changed

+118
-20
lines changed

5 files changed

+118
-20
lines changed

server/src/main/java/org/eclipse/lsp/cobol/core/preprocessor/TextPreprocessor.java

+28-1
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,38 @@ public interface TextPreprocessor {
3232
ResultWithErrors<ExtendedDocument> process(
3333
String documentUri, String cobolCode, CopybookConfig copybookConfig);
3434

35-
ResultWithErrors<ExtendedDocument> process(
35+
/**
36+
* Process cleaned up code
37+
*
38+
* @param documentUri unique resource identifier of the processed document
39+
* @param cobolCode cleaned code derived from the content of the document that should be processed
40+
* @param semanticContext stack, representing the hierarchy of nesting copybooks
41+
* @param copybookConfig contains config info like: copybook processing mode, target backend sql
42+
* server
43+
* @param recursiveReplaceStmtStack stack, representing the hierarchy of nested copy replace
44+
* @param replacingClauses list of replace clause generated by REPLACE compiler directives.
45+
* @return wrapped object containing extended document and related errors
46+
*/
47+
ResultWithErrors<ExtendedDocument> processCleanCode(
3648
String documentUri,
3749
String cobolCode,
3850
Deque<CopybookUsage> semanticContext,
3951
CopybookConfig copybookConfig,
4052
Deque<List<Pair<String, String>>> recursiveReplaceStmtStack,
4153
List<Pair<String, String>> replacingClauses);
54+
55+
/**
56+
* Checks and clean of the code as per cobol program structure.
57+
* Like
58+
* - checking code length doesn't exceeds 80 char
59+
* - removing line number and sequence number from source.
60+
* - concatenating continued lines
61+
* - Normalizing files in case of any compiler directives
62+
*
63+
* @param documentUri unique resource identifier of the processed document
64+
* @param cobolCode the content of the document that should be processed
65+
* @return modified code wrapped object and list of syntax error that might send back to the
66+
* client
67+
*/
68+
ResultWithErrors<String> cleanUpCode(String documentUri, String cobolCode);
4269
}

server/src/main/java/org/eclipse/lsp/cobol/core/preprocessor/TextPreprocessorImpl.java

+26-17
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,19 @@ public ResultWithErrors<ExtendedDocument> process(
7777
@NonNull String documentUri,
7878
@NonNull String cobolSourceCode,
7979
@NonNull CopybookConfig copybookConfig) {
80-
return process(
81-
documentUri,
82-
cobolSourceCode,
83-
new ArrayDeque<>(),
84-
copybookConfig,
85-
new ArrayDeque<>(),
86-
new ArrayList<>());
80+
ThreadInterruptionUtil.checkThreadInterrupted();
81+
List<SyntaxError> errors = new ArrayList<>();
82+
String cleanUpCode = cleanUpCode(documentUri, cobolSourceCode).unwrap(errors::addAll);
83+
ExtendedDocument extendedDocument =
84+
processCleanCode(
85+
documentUri,
86+
cleanUpCode,
87+
new ArrayDeque<>(),
88+
copybookConfig,
89+
new ArrayDeque<>(),
90+
new ArrayList<>())
91+
.unwrap(errors::addAll);
92+
return new ResultWithErrors<>(extendedDocument, errors);
8793
}
8894

8995
/**
@@ -98,27 +104,19 @@ public ResultWithErrors<ExtendedDocument> process(
98104
*/
99105
@NonNull
100106
@Override
101-
public ResultWithErrors<ExtendedDocument> process(
107+
public ResultWithErrors<ExtendedDocument> processCleanCode(
102108
@NonNull String documentUri,
103109
@NonNull String cobolCode,
104110
@NonNull Deque<CopybookUsage> copybookStack,
105111
@NonNull CopybookConfig copybookConfig,
106112
@NonNull Deque<List<Pair<String, String>>> recursiveReplaceStmtStack,
107113
@NonNull List<Pair<String, String>> replacingClauses) {
108-
ThreadInterruptionUtil.checkThreadInterrupted();
109114
List<SyntaxError> errors = new ArrayList<>();
110-
111-
List<CobolLine> lines = readLines(cobolCode, documentUri).unwrap(errors::addAll);
112-
List<CobolLine> transformedLines = transformLines(documentUri, lines).unwrap(errors::addAll);
113-
List<CobolLine> rewrittenLines = rewriteLines(transformedLines);
114-
115-
String code = writer.serialize(rewrittenLines);
116-
117115
ExtendedDocument parsedDocument =
118116
grammarPreprocessor
119117
.buildExtendedDocument(
120118
documentUri,
121-
code,
119+
cobolCode,
122120
copybookStack,
123121
copybookConfig,
124122
recursiveReplaceStmtStack,
@@ -128,6 +126,17 @@ public ResultWithErrors<ExtendedDocument> process(
128126
return new ResultWithErrors<>(parsedDocument, errors);
129127
}
130128

129+
@Override
130+
public ResultWithErrors<String> cleanUpCode(String documentUri, String cobolCode) {
131+
List<SyntaxError> errors = new ArrayList<>();
132+
List<CobolLine> lines = readLines(cobolCode, documentUri).unwrap(errors::addAll);
133+
List<CobolLine> transformedLines = transformLines(documentUri, lines).unwrap(errors::addAll);
134+
List<CobolLine> rewrittenLines = rewriteLines(transformedLines);
135+
136+
String code = writer.serialize(rewrittenLines);
137+
return new ResultWithErrors<>(code, errors);
138+
}
139+
131140
private ResultWithErrors<List<CobolLine>> readLines(String cobolCode, String documentURI) {
132141
return reader.processLines(documentURI, cobolCode);
133142
}

server/src/main/java/org/eclipse/lsp/cobol/core/preprocessor/delegates/GrammarPreprocessorListenerImpl.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ private void collectAndAccumulateCopybookData(
201201
recursiveReplaceStmtStack.add(new ArrayList<>(copyReplacingClauses));
202202
copyReplacingClauses.clear();
203203
}
204+
205+
// Do preprocessor cleanup, before replacements.
206+
content = preprocessor.cleanUpCode(uri, content).unwrap(errors::addAll);
207+
204208
if (!recursiveReplaceStmtStack.isEmpty()) {
205209
for (List<Pair<String, String>> clause : recursiveReplaceStmtStack)
206210
content = applyReplacing(content, clause);
@@ -383,7 +387,7 @@ private ExtendedDocument processCopybook(
383387
copybookStack.push(new CopybookUsage(copybookName, copybookId, locality));
384388
ExtendedDocument result =
385389
preprocessor
386-
.process(
390+
.processCleanCode(
387391
uri,
388392
content,
389393
copybookStack,

server/src/main/java/org/eclipse/lsp/cobol/core/preprocessor/delegates/util/ReplacingServiceImpl.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import lombok.Getter;
2121
import lombok.NonNull;
2222
import lombok.extern.slf4j.Slf4j;
23+
import org.apache.commons.lang3.StringUtils;
2324
import org.apache.commons.lang3.tuple.Pair;
2425
import org.eclipse.lsp.cobol.core.model.ErrorSeverity;
2526
import org.eclipse.lsp.cobol.core.model.ResultWithErrors;
@@ -206,11 +207,12 @@ private String handleSeparator(String trim) {
206207

207208
@NonNull
208209
private String replace(@NonNull String text, @NonNull Pair<String, String> pattern) {
210+
if (StringUtils.isBlank(text)) return text;
209211
String result = text;
210212
try {
211213
result = Pattern.compile(pattern.getLeft()).matcher(text).replaceAll(pattern.getRight());
212214
} catch (IndexOutOfBoundsException e) {
213-
LOG.error(format(ERROR_REPLACING, text, pattern.toString()), e);
215+
LOG.error(format(ERROR_REPLACING, text, pattern), e);
214216
}
215217
return result;
216218
}

server/src/test/java/org/eclipse/lsp/cobol/usecases/TestCopybookReplacePatterns.java

+56
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,28 @@ class TestCopybookReplacePatterns {
5959
+ "8 PROCEDURE DIVISION.\n"
6060
+ "9 MOVE 0 TO {$TAG_BY-IDS}.";
6161

62+
private static final String TEXT5 =
63+
BASE
64+
+ " 01 {$*LOGA}. \r\n"
65+
+ " COPY {~REPL5} \r\n"
66+
+ " REPLACING ==LDAY== BY ==DMAN123000000000000000000000000000000005900\n"
67+
+ " - 0000000000000000011111111111111111111111111111111111111111111\n"
68+
+ " - 00000000000000000000000== .\r\n";
69+
70+
private static final String TEXT6 =
71+
BASE
72+
+ "5 COPY {~REPL6} REPLACING ==:TAG:== BY == A ==.\r\n"
73+
+ "8 PROCEDURE DIVISION.\r\n"
74+
+ "9 MOVE 0 TO {$A_ID}.";
75+
76+
private static final String TEXT7 =
77+
BASE
78+
+ " 01 {$*LOGA}. \r\n"
79+
+ " COPY {~REPL7} \r\n"
80+
+ " REPLACING ==LDAY== BY ==DMAN123000000000000000000000000000000005900\n"
81+
+ " - 0000000000000000011111111111111111111111111111111111111111111\n"
82+
+ " - 00000000000000000000000== .\r\n";
83+
6284
private static final String REPL = "0 01 {$*TAG_ID} PIC 9.\n";
6385
private static final String REPL_NAME = "REPL";
6486

@@ -71,6 +93,22 @@ class TestCopybookReplacePatterns {
7193
private static final String REPL4 = "0 01 {$*TAG_ID^TAG_BY-IDS} PIC 9.\n";
7294
private static final String REPL4_NAME = "REPL4";
7395

96+
private static final String REPL5 =
97+
" ***************************************************************** 09700000\r\n"
98+
+ " 02 {$*LOGHDR}. 18000000\r\n"
99+
+ " 03 {$*LDAY^DMAN1230000000000000000000000000000000000000000000001111111111111111111111111111111111111111111100000000000000000000000} PIC S9(7) COMP-3. 24000000";
100+
private static final String REPL5_NAME = "REPL5";
101+
102+
private static final String REPL6 =
103+
"0 01 {$*:TAG:_ID^A_ID} PIC 9. 00007100";
104+
private static final String REPL6_NAME = "REPL6";
105+
106+
private static final String REPL7 =
107+
" ***************************************************************** 09700000\r\n"
108+
+ " 02 {$*LOGHDR}. 18000000\r\n"
109+
+ " 03 {$*LDAY^DMAN1230000000000000000000000000000000000000000000001111111111111111111111111111111111111111111100000000000000000000000} PIC S9(7) COMP-3.";
110+
private static final String REPL7_NAME = "REPL7";
111+
74112
@Test
75113
void testPartialTextAreNotReplaced() {
76114
UseCaseEngine.runTest(
@@ -102,4 +140,22 @@ void testPartialTextReplaceableWithTrailingClause() {
102140
UseCaseEngine.runTest(
103141
TEXT4, ImmutableList.of(new CobolText(REPL4_NAME, REPL4)), ImmutableMap.of());
104142
}
143+
144+
@Test
145+
void testWhenReplacedLengthIsMoreThanReplaceable() {
146+
UseCaseEngine.runTest(
147+
TEXT5, ImmutableList.of(new CobolText(REPL5_NAME, REPL5)), ImmutableMap.of());
148+
}
149+
150+
@Test
151+
void testWhenReplacedLengthIsLessThanReplaceable() {
152+
UseCaseEngine.runTest(
153+
TEXT6, ImmutableList.of(new CobolText(REPL6_NAME, REPL6)), ImmutableMap.of());
154+
}
155+
156+
@Test
157+
void testWhenReplacedLengthIsMoreThanReplaceableAndCopybookHasNoSequence() {
158+
UseCaseEngine.runTest(
159+
TEXT7, ImmutableList.of(new CobolText(REPL7_NAME, REPL7)), ImmutableMap.of());
160+
}
105161
}

0 commit comments

Comments
 (0)