Skip to content

Commit b70bfea

Browse files
committed
refactoring
1 parent 19eea51 commit b70bfea

File tree

5 files changed

+122
-63
lines changed

5 files changed

+122
-63
lines changed

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

Lines changed: 107 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
package com.igormaznitsa.jcp.containers;
2323

2424
import static java.util.Objects.requireNonNull;
25+
import static java.util.Objects.requireNonNullElse;
2526

2627
import com.igormaznitsa.jcp.context.CommentTextProcessor;
2728
import com.igormaznitsa.jcp.context.PreprocessingState;
@@ -404,8 +405,37 @@ private String extractSingleDollarPrefixedDirective(final String line,
404405
return tail;
405406
}
406407

408+
private static int findLastReadLineIndex(final PreprocessingState state) {
409+
if (state == null) {
410+
return -1;
411+
}
412+
413+
var fileData = state.peekFile();
414+
if (fileData == null) {
415+
return -1;
416+
} else {
417+
return fileData.getLastReadStringIndex();
418+
}
419+
}
420+
421+
/**
422+
* Preprocess the file described by the object, <b>NB! it doesn't clear local variables automatically for cloned contexts</b>
423+
*
424+
* @param state the start preprocessing state, can be null
425+
* @param context the preprocessor context, must not be null
426+
* @return the state for the preprocessed file
427+
* @throws IOException it will be thrown for IO errors
428+
* @throws PreprocessorException it will be thrown for violation of preprocessing logic, like undefined variable
429+
* @see #preprocessFileWithNotification(PreprocessingState, PreprocessorContext, boolean)
430+
*/
431+
public PreprocessingState preprocessFile(final PreprocessingState state,
432+
final PreprocessorContext context) throws IOException {
433+
return this.preprocessFileWithNotification(state, context, true);
434+
}
435+
407436
private void flushTextBufferForRemovedComments(
408437
final AtomicReference<Map.Entry<String, String>> firstDetectedUncommentLinePtr,
438+
final int stringIndex,
409439
final StringBuilder textBuffer,
410440
final ResetablePrinter resetablePrinter,
411441
final PreprocessingState state,
@@ -424,9 +454,11 @@ private void flushTextBufferForRemovedComments(
424454
if (!processors.isEmpty()) {
425455
processors.forEach(x -> {
426456
try {
457+
final FilePositionInfo filePositionInfo =
458+
new FilePositionInfo(this.sourceFile, stringIndex);
427459
final String result = x.onUncommentText(
428460
firstUncommentLine == null ? 0 : firstUncommentLine.getKey().length(), origText,
429-
this, context, state);
461+
filePositionInfo, this, context, state);
430462
textBuffer.append(result);
431463
} catch (Exception ex) {
432464
throw new PreprocessorException(
@@ -442,21 +474,6 @@ private void flushTextBufferForRemovedComments(
442474
}
443475
}
444476

445-
/**
446-
* Preprocess the file described by the object, <b>NB! it doesn't clear local variables automatically for cloned contexts</b>
447-
*
448-
* @param state the start preprocessing state, can be null
449-
* @param context the preprocessor context, must not be null
450-
* @return the state for the preprocessed file
451-
* @throws IOException it will be thrown for IO errors
452-
* @throws PreprocessorException it will be thrown for violation of preprocessing logic, like undefined variable
453-
* @see #preprocessFileWithNotification(PreprocessingState, PreprocessorContext, boolean)
454-
*/
455-
public PreprocessingState preprocessFile(final PreprocessingState state,
456-
final PreprocessorContext context) throws IOException {
457-
return this.preprocessFileWithNotification(state, context, true);
458-
}
459-
460477
/**
461478
* Preprocess the file described by the object, <b>NB! it doesn't clear local variables automatically for cloned contexts</b>
462479
*
@@ -477,7 +494,7 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
477494
context.fireNotificationStart();
478495
}
479496

480-
PreprocessingState preprocessingState = null;
497+
PreprocessingState theState = null;
481498
Throwable error = null;
482499
try {
483500
// do not clear local variables for cloned context to keep them in the new context
@@ -486,28 +503,29 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
486503
}
487504

488505
if (state == null) {
489-
preprocessingState = context.produceNewPreprocessingState(this, 1);
506+
theState = context.produceNewPreprocessingState(this, 1);
490507
} else {
491-
preprocessingState = state;
508+
theState = state;
492509
}
493510

494511
String leftTrimmedString = null;
495512

496513
TextFileDataContainer lastTextFileDataContainer = null;
497514
final StringBuilder textBlockBuffer = new StringBuilder();
498515

516+
Integer firstBlockLineIndex = null;
499517
try {
500518
final AtomicReference<Map.Entry<String, String>> firstUncommentLine =
501519
new AtomicReference<>();
502520

503521
while (!Thread.currentThread().isInterrupted()) {
504522
final ResetablePrinter thePrinter =
505-
requireNonNull(preprocessingState.getPrinter(), "Printer must be defined");
523+
requireNonNull(theState.getPrinter(), "Printer must be defined");
506524

507-
String rawString = preprocessingState.nextLine();
508-
final boolean presentedNextLine = preprocessingState.hasReadLineNextLineInEnd();
525+
String rawString = theState.nextLine();
526+
final boolean presentedNextLine = theState.hasReadLineNextLineInEnd();
509527

510-
final Set<PreprocessingFlag> processFlags = preprocessingState.getPreprocessingFlags();
528+
final Set<PreprocessingFlag> processFlags = theState.getPreprocessingFlags();
511529

512530
if (processFlags.contains(PreprocessingFlag.END_PROCESSING) ||
513531
processFlags.contains(PreprocessingFlag.ABORT_PROCESSING)) {
@@ -517,18 +535,22 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
517535
rawString = null;
518536
}
519537

520-
if (preprocessingState.getPreprocessingFlags()
538+
if (theState.getPreprocessingFlags()
521539
.contains(PreprocessingFlag.END_PROCESSING)) {
522-
preprocessingState.getPreprocessingFlags().remove(PreprocessingFlag.END_PROCESSING);
540+
theState.getPreprocessingFlags().remove(PreprocessingFlag.END_PROCESSING);
523541
rawString = null;
524542
}
525543

526544
if (rawString == null) {
527-
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer, thePrinter,
528-
preprocessingState,
545+
this.flushTextBufferForRemovedComments(
546+
firstUncommentLine,
547+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
548+
textBlockBuffer, thePrinter,
549+
theState,
529550
context);
530-
lastTextFileDataContainer = preprocessingState.popTextContainer();
531-
if (preprocessingState.isIncludeStackEmpty()) {
551+
firstBlockLineIndex = null;
552+
lastTextFileDataContainer = theState.popTextContainer();
553+
if (theState.isIncludeStackEmpty()) {
532554
break;
533555
} else {
534556
continue;
@@ -554,12 +576,16 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
554576
final boolean doPrintLn = presentedNextLine || !context.isCareForLastEol();
555577

556578
if (isHashPrefixed(stringToBeProcessed, context)) {
557-
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer, thePrinter,
558-
preprocessingState,
579+
this.flushTextBufferForRemovedComments(firstUncommentLine,
580+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
581+
textBlockBuffer,
582+
thePrinter,
583+
theState,
559584
context);
585+
firstBlockLineIndex = null;
560586
final String extractedDirective =
561587
extractHashPrefixedDirective(stringToBeProcessed, context);
562-
switch (processDirective(preprocessingState, extractedDirective, context, false)) {
588+
switch (processDirective(theState, extractedDirective, context, false)) {
563589
case PROCESSED:
564590
case READ_NEXT_LINE: {
565591
if (context.isKeepLines()) {
@@ -590,8 +616,8 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
590616
}
591617
}
592618

593-
if (preprocessingState.isDirectiveCanBeProcessed() &&
594-
!preprocessingState.getPreprocessingFlags()
619+
if (theState.isDirectiveCanBeProcessed() &&
620+
!theState.getPreprocessingFlags()
595621
.contains(PreprocessingFlag.TEXT_OUTPUT_DISABLED)) {
596622
final boolean startsWithTwoDollars =
597623
isDoubleDollarPrefixed(leftTrimmedString, context.isAllowWhitespaces());
@@ -614,24 +640,32 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
614640
indentText = Map.entry(context.isPreserveIndents() ? stringPrefix : "", text);
615641

616642
if (firstLineSet) {
643+
firstBlockLineIndex = findLastReadLineIndex(theState);
617644
firstUncommentLine.set(indentText);
618645
}
619646
textBlockBuffer.append(indentText.getValue());
620647
if (doPrintLn) {
621648
textBlockBuffer.append(context.getEol());
622649
}
623650
} else {
624-
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
651+
this.flushTextBufferForRemovedComments(firstUncommentLine,
652+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
653+
textBlockBuffer,
625654
thePrinter,
626-
preprocessingState, context);
655+
theState, context);
656+
firstBlockLineIndex = null;
657+
627658
textBlockBuffer.append(stringPrefix).append(indentText.getKey())
628659
.append(indentText.getValue());
629660
if (doPrintLn) {
630661
textBlockBuffer.append(context.getEol());
631662
}
632-
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
663+
this.flushTextBufferForRemovedComments(firstUncommentLine,
664+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
665+
textBlockBuffer,
633666
thePrinter,
634-
preprocessingState, context);
667+
theState, context);
668+
firstBlockLineIndex = null;
635669
}
636670
} else if (isSingleDollarPrefixed(stringToBeProcessed, context.isAllowWhitespaces())) {
637671
// Output the tail of the string to the output stream without comments
@@ -648,6 +682,7 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
648682
indentText = Map.entry(context.isPreserveIndents() ? stringPrefix : "", text);
649683

650684
if (firstLineSet) {
685+
firstBlockLineIndex = findLastReadLineIndex(theState);
651686
firstUncommentLine.set(indentText);
652687
}
653688

@@ -656,30 +691,41 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
656691
textBlockBuffer.append(context.getEol());
657692
}
658693
} else {
659-
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
694+
this.flushTextBufferForRemovedComments(firstUncommentLine,
695+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
696+
textBlockBuffer,
660697
thePrinter,
661-
preprocessingState, context);
698+
theState, context);
699+
firstBlockLineIndex = null;
700+
662701
textBlockBuffer.append(stringPrefix).append(indentText.getKey())
663702
.append(indentText.getValue());
664703
if (doPrintLn) {
665704
textBlockBuffer.append(context.getEol());
666705
}
667-
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
706+
this.flushTextBufferForRemovedComments(
707+
firstUncommentLine,
708+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
709+
textBlockBuffer,
668710
thePrinter,
669-
preprocessingState, context);
711+
theState, context);
712+
firstBlockLineIndex = null;
670713
}
671714
} else {
672715
// Just string
673-
this.flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer,
716+
this.flushTextBufferForRemovedComments(firstUncommentLine,
717+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
718+
textBlockBuffer,
674719
thePrinter,
675-
preprocessingState, context);
720+
theState, context);
721+
firstBlockLineIndex = null;
676722

677723
final String strToOut = findTailRemover(stringToBeProcessed, context);
678724

679-
if (preprocessingState.getPreprocessingFlags()
725+
if (theState.getPreprocessingFlags()
680726
.contains(PreprocessingFlag.COMMENT_NEXT_LINE)) {
681727
thePrinter.print(AbstractDirectiveHandler.ONE_LINE_COMMENT);
682-
preprocessingState.getPreprocessingFlags()
728+
theState.getPreprocessingFlags()
683729
.remove(PreprocessingFlag.COMMENT_NEXT_LINE);
684730
}
685731

@@ -691,9 +737,15 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
691737
}
692738
}
693739
} else if (context.isKeepLines()) {
694-
flushTextBufferForRemovedComments(firstUncommentLine, textBlockBuffer, thePrinter,
695-
preprocessingState,
740+
741+
flushTextBufferForRemovedComments(firstUncommentLine,
742+
requireNonNullElse(firstBlockLineIndex, findLastReadLineIndex(theState)),
743+
textBlockBuffer,
744+
thePrinter,
745+
theState,
696746
context);
747+
firstBlockLineIndex = null;
748+
697749
final String text = AbstractDirectiveHandler.PREFIX_FOR_KEEPING_LINES + rawString;
698750
if (doPrintLn) {
699751
thePrinter.println(text, context.getEol());
@@ -705,20 +757,20 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
705757
} catch (Exception unexpected) {
706758
final String message =
707759
unexpected.getMessage() == null ? "Unexpected exception" : unexpected.getMessage();
708-
throw preprocessingState.makeException(message, leftTrimmedString, unexpected);
760+
throw theState.makeException(message, leftTrimmedString, unexpected);
709761
}
710762

711-
if (!preprocessingState.isIfStackEmpty()) {
763+
if (!theState.isIfStackEmpty()) {
712764
final TextFileDataContainer lastIf =
713-
requireNonNull(preprocessingState.peekIf(), "'IF' stack is empty");
765+
requireNonNull(theState.peekIf(), "'IF' stack is empty");
714766
throw new PreprocessorException(
715767
"Unclosed " + AbstractDirectiveHandler.DIRECTIVE_PREFIX + "if instruction detected",
716768
"", new FilePositionInfo[] {
717769
new FilePositionInfo(lastIf.getFile(), lastIf.getNextStringIndex())}, null);
718770
}
719-
if (!preprocessingState.isWhileStackEmpty()) {
771+
if (!theState.isWhileStackEmpty()) {
720772
final TextFileDataContainer lastWhile =
721-
requireNonNull(preprocessingState.peekWhile(), "'WHILE' stack is empty");
773+
requireNonNull(theState.peekWhile(), "'WHILE' stack is empty");
722774
throw new PreprocessorException(
723775
"Unclosed " + AbstractDirectiveHandler.DIRECTIVE_PREFIX + "while instruction detected",
724776
"", new FilePositionInfo[] {
@@ -729,7 +781,7 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
729781
final File outFile = context.createDestinationFileForPath(makeTargetFilePathAsString());
730782

731783
final boolean wasSaved =
732-
preprocessingState.saveBuffersToFile(outFile, context.getKeepComments());
784+
theState.saveBuffersToFile(outFile, context.getKeepComments());
733785

734786
if (context.isVerbose()) {
735787
context.logForVerbose(String
@@ -760,7 +812,7 @@ public PreprocessingState preprocessFileWithNotification(final PreprocessingStat
760812
context.fireNotificationStop(error);
761813
}
762814
}
763-
return preprocessingState;
815+
return theState;
764816
}
765817

766818
private boolean checkDirectiveArgumentRoughly(final AbstractDirectiveHandler directive,

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.igormaznitsa.jcp.context;
22

33
import com.igormaznitsa.jcp.containers.FileInfoContainer;
4+
import com.igormaznitsa.jcp.exceptions.FilePositionInfo;
45
import java.io.IOException;
56

67
/**
@@ -13,11 +14,13 @@
1314
* @since 7.2.0
1415
*/
1516
public interface CommentTextProcessor extends PreprocessorContextListener {
17+
1618
/**
1719
* Process text value.
1820
*
1921
* @param firstLineIndent detected indent for the first line during accumulation
2022
* @param text the source text
23+
* @param filePositionInfo position of the uncommented line or the first line of the uncommented text block
2124
* @param fileInfoContainer the source file info container, must not be null
2225
* @param context the source preprocessor context, must not be null
2326
* @param state the current preprocess state, must not be null
@@ -28,6 +31,7 @@ public interface CommentTextProcessor extends PreprocessorContextListener {
2831
String onUncommentText(
2932
int firstLineIndent,
3033
String text,
34+
FilePositionInfo filePositionInfo,
3135
FileInfoContainer fileInfoContainer,
3236
PreprocessorContext context,
3337
PreprocessingState state) throws IOException;

jcp/src/main/java/com/igormaznitsa/jcp/exceptions/FilePositionInfo.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ public int getLineNumber() {
7373
}
7474

7575
@Override
76-
7776
public String toString() {
7877
final String filePath = PreprocessorUtils.getFilePath(this.file);
7978
return filePath + ':' + this.getLineNumber();

0 commit comments

Comments
 (0)