|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.github.javaparser.printer; |
|
|
|
import java.util.Deque; |
|
import java.util.LinkedList; |
|
|
|
import com.github.javaparser.Position; |
|
import com.github.javaparser.printer.configuration.DefaultConfigurationOption; |
|
import com.github.javaparser.printer.configuration.DefaultPrinterConfiguration; |
|
import com.github.javaparser.printer.configuration.DefaultPrinterConfiguration.ConfigOption; |
|
import com.github.javaparser.printer.configuration.Indentation; |
|
import com.github.javaparser.printer.configuration.Indentation.IndentType; |
|
import com.github.javaparser.printer.configuration.PrettyPrinterConfiguration; |
|
import com.github.javaparser.printer.configuration.PrinterConfiguration; |
|
import com.github.javaparser.utils.Utils; |
|
|
|
|
|
|
|
*/ |
|
public class SourcePrinter { |
|
private String endOfLineCharacter; |
|
private Indentation indentation; |
|
|
|
private final Deque<String> indents = new LinkedList<>(); |
|
private final Deque<String> reindentedIndents = new LinkedList<>(); |
|
private String lastPrintedIndent = ""; |
|
private final StringBuilder buf = new StringBuilder(); |
|
private Position cursor = new Position(Position.FIRST_LINE, Position.FIRST_COLUMN - 1); |
|
private boolean indented = false; |
|
|
|
SourcePrinter() { |
|
this(new DefaultPrinterConfiguration()); |
|
} |
|
|
|
SourcePrinter(final PrettyPrinterConfiguration configuration) { |
|
this(configuration.getIndentation(), configuration.getEndOfLineCharacter()); |
|
} |
|
|
|
SourcePrinter(final PrinterConfiguration configuration) { |
|
this(configuration.get(new DefaultConfigurationOption(ConfigOption.INDENTATION)).get().asValue(), |
|
configuration.get(new DefaultConfigurationOption(ConfigOption.END_OF_LINE_CHARACTER)).get().asString()); |
|
} |
|
|
|
SourcePrinter(Indentation indentation, String eol) { |
|
this.indentation = indentation; |
|
this.endOfLineCharacter = eol; |
|
indents.push(""); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public SourcePrinter indent() { |
|
String currentIndent = indents.peek(); |
|
switch (indentation.getType()) { |
|
case SPACES: |
|
case TABS_WITH_SPACE_ALIGN: |
|
indents.push(currentIndent + indentation.getIndent()); |
|
break; |
|
|
|
case TABS: |
|
indents.push(indentation.getIndent() + currentIndent); |
|
break; |
|
|
|
default: |
|
throw new AssertionError("Unhandled indent type"); |
|
} |
|
return this; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public SourcePrinter indentWithAlignTo(int column) { |
|
indents.push(calculateIndentWithAlignTo(column)); |
|
return this; |
|
} |
|
|
|
private String calculateIndentWithAlignTo(int column) { |
|
if (column < lastPrintedIndent.length()){ |
|
throw new IllegalStateException("Attempt to indent less than the previous indent."); |
|
} |
|
|
|
StringBuilder newIndent = new StringBuilder(lastPrintedIndent); |
|
switch (indentation.getType()) { |
|
case SPACES: |
|
case TABS_WITH_SPACE_ALIGN: |
|
while (newIndent.length() < column) { |
|
newIndent.append(IndentType.SPACES.getCar()); |
|
} |
|
break; |
|
|
|
case TABS: |
|
IndentType currentIndentType = indentation.getType(); |
|
int logicalIndentLength = newIndent.length(); |
|
while ((logicalIndentLength + currentIndentType.getWidth()) <= column) { |
|
newIndent.insert(0, currentIndentType.getCar()); |
|
logicalIndentLength += currentIndentType.getWidth(); |
|
} |
|
while (logicalIndentLength < column) { |
|
newIndent.append(IndentType.SPACES.getCar()); |
|
logicalIndentLength++; |
|
} |
|
StringBuilder fullTab = new StringBuilder(); |
|
for(int i=0; i<currentIndentType.getWidth(); i++){ |
|
fullTab.append(IndentType.SPACES.getCar()); |
|
} |
|
String fullTabString = fullTab.toString(); |
|
if ((newIndent.length() >= currentIndentType.getWidth()) |
|
&& newIndent.substring(newIndent.length() - currentIndentType.getWidth()).equals(fullTabString)) { |
|
int i = newIndent.indexOf(fullTabString); |
|
newIndent.replace(i, i + currentIndentType.getWidth(), currentIndentType.getCar().toString()); |
|
} |
|
break; |
|
|
|
default: |
|
throw new AssertionError("Unhandled indent type"); |
|
} |
|
|
|
return newIndent.toString(); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public SourcePrinter unindent() { |
|
if (indents.isEmpty()) { |
|
// Since we start out with an empty indent on the stack, this will only occur |
|
|
|
throw new IllegalStateException("Indent/unindent calls are not well-balanced."); |
|
} |
|
indents.pop(); |
|
return this; |
|
} |
|
|
|
private void append(String arg) { |
|
buf.append(arg); |
|
cursor = cursor.withColumn(cursor.column + arg.length()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public SourcePrinter print(final String arg) { |
|
if (!indented) { |
|
lastPrintedIndent = indents.peek(); |
|
append(lastPrintedIndent); |
|
indented = true; |
|
} |
|
append(arg); |
|
return this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public SourcePrinter println(final String arg) { |
|
print(arg); |
|
println(); |
|
return this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public SourcePrinter println() { |
|
buf.append(endOfLineCharacter); |
|
cursor = new Position(cursor.line + 1, Position.FIRST_COLUMN - 1); |
|
indented = false; |
|
return this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Position getCursor() { |
|
return cursor; |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
@Deprecated |
|
public String getSource() { |
|
return toString(); |
|
} |
|
|
|
|
|
|
|
*/ |
|
@Override |
|
public String toString() { |
|
return buf.toString(); |
|
} |
|
|
|
|
|
|
|
*/ |
|
public String normalizeEolInTextBlock(String content) { |
|
return Utils.normalizeEolInTextBlock(content, endOfLineCharacter); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void reindentWithAlignToCursor() { |
|
String newIndent = calculateIndentWithAlignTo(cursor.column); |
|
reindentedIndents.push(indents.pop()); |
|
indents.push(newIndent); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void reindentToPreviousLevel() { |
|
if (reindentedIndents.isEmpty()) { |
|
throw new IllegalStateException("Reindent calls are not well-balanced."); |
|
} |
|
indents.pop(); |
|
indents.push(reindentedIndents.pop()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void duplicateIndent() { |
|
indents.push(indents.peek()); |
|
} |
|
} |