Skip to content

Commit 19eea51

Browse files
committed
refactoring
1 parent 1951da4 commit 19eea51

File tree

6 files changed

+130
-62
lines changed

6 files changed

+130
-62
lines changed

jcp/src/main/java/com/igormaznitsa/jcp/containers/FileInfoContainer.java

Lines changed: 69 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
import java.util.Collection;
3939
import java.util.HashSet;
4040
import java.util.List;
41+
import java.util.Map;
4142
import java.util.Set;
43+
import java.util.concurrent.atomic.AtomicReference;
4244
import java.util.regex.Matcher;
4345
import java.util.regex.Pattern;
4446
import lombok.Data;
@@ -344,9 +346,10 @@ private String extractHashPrefixedDirective(final String line,
344346
}
345347

346348

347-
private String extractDoubleDollarPrefixedDirective(final String line,
348-
final boolean block,
349-
final PreprocessorContext context) {
349+
private String extractDoubleDollarPrefixedDirective(
350+
final String line,
351+
final boolean block,
352+
final PreprocessorContext context) {
350353
String tail;
351354
if (context.isAllowWhitespaces()) {
352355
final Matcher matcher = block ? DIRECTIVE_TWO_DOLLARS_BLOCK_PREFIXED.matcher(line) :
@@ -401,11 +404,17 @@ private String extractSingleDollarPrefixedDirective(final String line,
401404
return tail;
402405
}
403406

404-
private void flushTextBufferForRemovedComments(final StringBuilder textBuffer,
405-
final ResetablePrinter resetablePrinter,
406-
final PreprocessingState state,
407-
final PreprocessorContext context)
407+
private void flushTextBufferForRemovedComments(
408+
final AtomicReference<Map.Entry<String, String>> firstDetectedUncommentLinePtr,
409+
final StringBuilder textBuffer,
410+
final ResetablePrinter resetablePrinter,
411+
final PreprocessingState state,
412+
final PreprocessorContext context)
408413
throws IOException {
414+
415+
final Map.Entry<String, String> firstUncommentLine =
416+
firstDetectedUncommentLinePtr.getAndSet(null);
417+
409418
if (textBuffer.length() > 0) {
410419
final List<CommentTextProcessor> processors = context.getCommentTextProcessors();
411420
final String origText = textBuffer.toString();
@@ -415,7 +424,9 @@ private void flushTextBufferForRemovedComments(final StringBuilder textBuffer,
415424
if (!processors.isEmpty()) {
416425
processors.forEach(x -> {
417426
try {
418-
final String result = x.onUncommentText(origText, this, context, state);
427+
final String result = x.onUncommentText(
428+
firstUncommentLine == null ? 0 : firstUncommentLine.getKey().length(), origText,
429+
this, context, state);
419430
textBuffer.append(result);
420431
} catch (Exception ex) {
421432
throw new PreprocessorException(
@@ -486,6 +497,9 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
486497
final StringBuilder textBlockBuffer = new StringBuilder();
487498

488499
try {
500+
final AtomicReference<Map.Entry<String, String>> firstUncommentLine =
501+
new AtomicReference<>();
502+
489503
while (!Thread.currentThread().isInterrupted()) {
490504
final ResetablePrinter thePrinter =
491505
requireNonNull(preprocessingState.getPrinter(), "Printer must be defined");
@@ -510,7 +524,8 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
510524
}
511525

512526
if (rawString == null) {
513-
this.flushTextBufferForRemovedComments(textBlockBuffer, thePrinter, preprocessingState,
527+
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer, thePrinter,
528+
preprocessingState,
514529
context);
515530
lastTextFileDataContainer = preprocessingState.popTextContainer();
516531
if (preprocessingState.isIncludeStackEmpty()) {
@@ -539,7 +554,8 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
539554
final boolean doPrintLn = presentedNextLine || !context.isCareForLastEol();
540555

541556
if (isHashPrefixed(stringToBeProcessed, context)) {
542-
this.flushTextBufferForRemovedComments(textBlockBuffer, thePrinter, preprocessingState,
557+
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer, thePrinter,
558+
preprocessingState,
543559
context);
544560
final String extractedDirective =
545561
extractHashPrefixedDirective(stringToBeProcessed, context);
@@ -585,51 +601,77 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
585601
}
586602

587603
if (startsWithTwoDollars) {
588-
// Output the tail of the string to the output stream without comments and macroses
589-
final String text =
590-
extractDoubleDollarPrefixedDirective(leftTrimmedString, false, context);
604+
// Output the tail of the string to the output stream without comments and macros
605+
String text = extractDoubleDollarPrefixedDirective(leftTrimmedString, false, context);
606+
Map.Entry<String, String> indentText =
607+
Map.entry(context.isPreserveIndents() ? stringPrefix : "", text);
608+
final boolean firstLineSet = firstUncommentLine.compareAndSet(null, indentText);
609+
591610
if (context.isAllowsBlocks() &&
592611
isDoubleDollarBlockPrefixed(leftTrimmedString, context.isAllowWhitespaces())) {
593-
textBlockBuffer.append(
594-
extractDoubleDollarPrefixedDirective(leftTrimmedString, true, context));
612+
text =
613+
extractDoubleDollarPrefixedDirective(leftTrimmedString, true, context);
614+
indentText = Map.entry(context.isPreserveIndents() ? stringPrefix : "", text);
615+
616+
if (firstLineSet) {
617+
firstUncommentLine.set(indentText);
618+
}
619+
textBlockBuffer.append(indentText.getValue());
595620
if (doPrintLn) {
596621
textBlockBuffer.append(context.getEol());
597622
}
598623
} else {
599-
this.flushTextBufferForRemovedComments(textBlockBuffer, thePrinter,
624+
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
625+
thePrinter,
600626
preprocessingState, context);
601-
textBlockBuffer.append(stringPrefix).append(text);
627+
textBlockBuffer.append(stringPrefix).append(indentText.getKey())
628+
.append(indentText.getValue());
602629
if (doPrintLn) {
603630
textBlockBuffer.append(context.getEol());
604631
}
605-
this.flushTextBufferForRemovedComments(textBlockBuffer, thePrinter,
632+
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
633+
thePrinter,
606634
preprocessingState, context);
607635
}
608636
} else if (isSingleDollarPrefixed(stringToBeProcessed, context.isAllowWhitespaces())) {
609637
// Output the tail of the string to the output stream without comments
610-
final String text =
638+
String text =
611639
extractSingleDollarPrefixedDirective(stringToBeProcessed, false, context);
640+
Map.Entry<String, String> indentText =
641+
Map.entry(context.isPreserveIndents() ? stringPrefix : "", text);
642+
final boolean firstLineSet = firstUncommentLine.compareAndSet(null, indentText);
612643

613644
if (context.isAllowsBlocks() &&
614645
isDollarBlockPrefixed(stringToBeProcessed, context.isAllowWhitespaces())) {
615-
textBlockBuffer.append(
616-
extractSingleDollarPrefixedDirective(stringToBeProcessed, true, context));
646+
text =
647+
extractSingleDollarPrefixedDirective(stringToBeProcessed, true, context);
648+
indentText = Map.entry(context.isPreserveIndents() ? stringPrefix : "", text);
649+
650+
if (firstLineSet) {
651+
firstUncommentLine.set(indentText);
652+
}
653+
654+
textBlockBuffer.append(indentText.getValue());
617655
if (doPrintLn) {
618656
textBlockBuffer.append(context.getEol());
619657
}
620658
} else {
621-
this.flushTextBufferForRemovedComments(textBlockBuffer, thePrinter,
659+
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
660+
thePrinter,
622661
preprocessingState, context);
623-
textBlockBuffer.append(stringPrefix).append(text);
662+
textBlockBuffer.append(stringPrefix).append(indentText.getKey())
663+
.append(indentText.getValue());
624664
if (doPrintLn) {
625665
textBlockBuffer.append(context.getEol());
626666
}
627-
this.flushTextBufferForRemovedComments(textBlockBuffer, thePrinter,
667+
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
668+
thePrinter,
628669
preprocessingState, context);
629670
}
630671
} else {
631672
// Just string
632-
this.flushTextBufferForRemovedComments(textBlockBuffer, thePrinter,
673+
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
674+
thePrinter,
633675
preprocessingState, context);
634676

635677
final String strToOut = findTailRemover(stringToBeProcessed, context);
@@ -649,7 +691,8 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
649691
}
650692
}
651693
} else if (context.isKeepLines()) {
652-
flushTextBufferForRemovedComments(textBlockBuffer, thePrinter, preprocessingState,
694+
flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer, thePrinter,
695+
preprocessingState,
653696
context);
654697
final String text = AbstractDirectiveHandler.PREFIX_FOR_KEEPING_LINES + rawString;
655698
if (doPrintLn) {

jcp/src/main/java/com/igormaznitsa/jcp/context/CommentTextProcessor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@ public interface CommentTextProcessor extends PreprocessorContextListener {
1616
/**
1717
* Process text value.
1818
*
19+
* @param firstLineIndent detected indent for the first line during accumulation
1920
* @param text the source text
2021
* @param fileInfoContainer the source file info container, must not be null
2122
* @param context the source preprocessor context, must not be null
2223
* @param state the current preprocess state, must not be null
2324
* @return must return value as the same text or as the changed one.
2425
* @throws IOException if any IO error during operation
26+
* @since 7.2.1
2527
*/
2628
String onUncommentText(
29+
int firstLineIndent,
2730
String text,
2831
FileInfoContainer fileInfoContainer,
2932
PreprocessorContext context,

jcp/src/test/java/com/igormaznitsa/jcp/directives/LinesNotMatchException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public String getResultString() {
6464
public String toString() {
6565
return LinesNotMatchException.class.getName() + "(etalonLineNum=" + this.etalonLineNumber
6666
+ ",resultLineNum=" + this.resultLineNumber
67-
+ ",problemLine" + (this.problemStringIndex + 1)
67+
+ ",problemLine=" + (this.problemStringIndex + 1)
6868
+ ",etalonString=" + this.etalonString
6969
+ ",resultString=" + this.resultString
7070
+ ')';

jcp/src/test/java/com/igormaznitsa/jcp/directives/SpecialDirectivesBlockTest.java

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
import com.igormaznitsa.jcp.context.CommentTextProcessor;
3131
import com.igormaznitsa.jcp.context.PreprocessingState;
3232
import com.igormaznitsa.jcp.context.PreprocessorContext;
33+
import java.util.Arrays;
3334
import java.util.concurrent.atomic.AtomicBoolean;
35+
import java.util.stream.Collectors;
3436

3537
// This test checks work of //$$""", //$"""
3638
// Those directives are very specific and they don't have any distinguished handler
@@ -59,49 +61,63 @@ public void onContextStopped(PreprocessorContext context, Throwable error) {
5961
}
6062

6163
@Override
62-
public String onUncommentText(String text, FileInfoContainer fileInfoContainer,
63-
PreprocessorContext context, PreprocessingState state) {
64+
public String onUncommentText(
65+
int firstLineIndent,
66+
String text,
67+
FileInfoContainer fileInfoContainer,
68+
PreprocessorContext context, PreprocessingState state) {
6469
assertNotNull(text);
6570
assertNotNull(fileInfoContainer);
6671
assertNotNull(context);
6772
assertNotNull(state);
6873

6974
calledForText.append("...\n").append(text);
7075

71-
return text;
76+
final String indent = context.isPreserveIndents() ? " ".repeat(firstLineIndent) : "";
77+
78+
return Arrays.stream(text.split("\\R"))
79+
.map(x -> indent + x)
80+
.peek(x -> System.out.println(">>>" + x))
81+
.collect(Collectors.joining(context.getEol(), "", context.getEol()));
7282
}
7383
};
7484

7585
assertFilePreprocessing("directive_special_block.txt", false, true, null, null,
76-
c -> c.addCommentTextProcessor(testProcessor));
86+
c -> {
87+
c.setPreserveIndents(true);
88+
c.addCommentTextProcessor(testProcessor);
89+
});
7790
assertTrue(started.get());
7891
assertTrue(stopped.get());
7992
assertEquals("...\n" +
80-
"hello 223 world\n" +
81-
"next\n" +
93+
" hello 223 world\n" +
94+
" next\n" +
95+
"...\n" +
96+
" hello /*$111+112$*/ world\n" +
97+
" next/*$111+112$*/\n" +
8298
"...\n" +
83-
"hello /*$111+112$*/ world\n" +
84-
"next/*$111+112$*/\n" +
99+
" hello /*$111+112$*/ world\n" +
100+
" middle\n" +
101+
" next/*$111+112$*/\n" +
85102
"...\n" +
86-
"hello /*$111+112$*/ world\n" +
87-
"middle\n" +
88-
"next/*$111+112$*/\n" +
103+
" hello /*$111+112$*/ world\n" +
89104
"...\n" +
90-
"hello /*$111+112$*/ world\n" +
105+
" split\n" +
91106
"...\n" +
92-
"split\n" +
107+
" next/*$111+112$*/\n" +
93108
"...\n" +
94-
"next/*$111+112$*/\n" +
109+
" hello 223 world\n" +
95110
"...\n" +
96-
"hello 223 world\n" +
111+
" split\n" +
97112
"...\n" +
98-
"split\n" +
113+
" next223\n" +
99114
"...\n" +
100-
"next223\n" +
115+
" line1\n" +
101116
"...\n" +
102-
"line1\n" +
117+
" line2\n" +
103118
"...\n" +
104-
"line2\n"
119+
" hello\n" +
120+
" world earth\n"
105121
, calledForText.toString());
106122
}
107123

jcp/src/test/java/com/igormaznitsa/jcp/directives/SpecialDirectivesTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public void onContextStopped(PreprocessorContext context, Throwable error) {
5959
}
6060

6161
@Override
62-
public String onUncommentText(String text, FileInfoContainer fileInfoContainer,
62+
public String onUncommentText(int indent, String text, FileInfoContainer fileInfoContainer,
6363
PreprocessorContext context, PreprocessingState state) {
6464
assertNotNull(text);
6565
assertNotNull(fileInfoContainer);

jcp/src/test/resources/com/igormaznitsa/jcp/directives/directive_special_block.txt

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,30 @@
1919
//$"""line1
2020
//#local a=""
2121
//$"""line2
22+
23+
//$"""hello
24+
//$"""world earth
2225
---START_ETALON---
23-
hello 223 world
24-
next
26+
hello 223 world
27+
next
28+
29+
hello /*$111+112$*/ world
30+
next/*$111+112$*/
2531

26-
hello /*$111+112$*/ world
27-
next/*$111+112$*/
32+
hello /*$111+112$*/ world
33+
middle
34+
next/*$111+112$*/
2835

29-
hello /*$111+112$*/ world
30-
middle
31-
next/*$111+112$*/
36+
hello /*$111+112$*/ world
37+
split
38+
next/*$111+112$*/
3239

33-
hello /*$111+112$*/ world
34-
split
35-
next/*$111+112$*/
40+
hello 223 world
41+
split
42+
next223
3643

37-
hello 223 world
38-
split
39-
next223
44+
line1
45+
line2
4046

41-
line1
42-
line2
47+
hello
48+
world earth

0 commit comments

Comments
 (0)