|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.github.javaparser.printer.lexicalpreservation; |
|
|
|
import com.github.javaparser.JavaToken; |
|
import com.github.javaparser.TokenRange; |
|
import com.github.javaparser.TokenTypes; |
|
import com.github.javaparser.ast.Node; |
|
import com.github.javaparser.printer.concretesyntaxmodel.CsmToken; |
|
|
|
import java.util.Iterator; |
|
import java.util.List; |
|
import java.util.Optional; |
|
import java.util.function.Function; |
|
import java.util.stream.Collectors; |
|
import java.util.stream.IntStream; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final class RemovedGroup implements Iterable<Removed> { |
|
|
|
private final Integer firstElementIndex; |
|
private final List<Removed> removedList; |
|
|
|
private boolean isProcessed = false; |
|
|
|
private RemovedGroup(Integer firstElementIndex, List<Removed> removedList) { |
|
if (firstElementIndex == null) { |
|
throw new IllegalArgumentException("firstElementIndex should not be null"); |
|
} |
|
|
|
if (removedList == null || removedList.isEmpty()) { |
|
throw new IllegalArgumentException("removedList should not be null or empty"); |
|
} |
|
|
|
this.firstElementIndex = firstElementIndex; |
|
this.removedList = removedList; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public static RemovedGroup of(Integer firstElementIndex, List<Removed> removedList) { |
|
return new RemovedGroup(firstElementIndex, removedList); |
|
} |
|
|
|
|
|
|
|
*/ |
|
final void processed() { |
|
isProcessed = true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final boolean isProcessed() { |
|
return isProcessed; |
|
} |
|
|
|
private List<Integer> getIndicesBeingRemoved() { |
|
return IntStream.range(firstElementIndex, firstElementIndex + removedList.size()) |
|
.boxed() |
|
.collect(Collectors.toList()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final Integer getLastElementIndex() { |
|
List<Integer> indicesBeingRemoved = getIndicesBeingRemoved(); |
|
return indicesBeingRemoved.get(indicesBeingRemoved.size() - 1); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final Removed getFirstElement() { |
|
return removedList.get(0); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final Removed getLastElement() { |
|
return removedList.get(removedList.size() - 1); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final boolean isACompleteLine() { |
|
return hasOnlyWhitespace(getFirstElement(), hasOnlyWhitespaceInFrontFunction) |
|
&& hasOnlyWhitespace(getLastElement(), hasOnlyWhitespaceBehindFunction); |
|
} |
|
|
|
private final Function<JavaToken, Boolean> hasOnlyWhitespaceJavaTokenInFrontFunction = begin -> hasOnlyWhiteSpaceForTokenFunction(begin, token -> token.getPreviousToken()); |
|
private final Function<JavaToken, Boolean> hasOnlyWhitespaceJavaTokenBehindFunction = end -> hasOnlyWhiteSpaceForTokenFunction(end, token -> token.getNextToken()); |
|
private final Function<TokenRange, Boolean> hasOnlyWhitespaceInFrontFunction = tokenRange -> hasOnlyWhitespaceJavaTokenInFrontFunction.apply(tokenRange.getBegin()); |
|
private final Function<TokenRange, Boolean> hasOnlyWhitespaceBehindFunction = tokenRange -> hasOnlyWhitespaceJavaTokenBehindFunction.apply(tokenRange.getEnd()); |
|
|
|
private boolean hasOnlyWhitespace(Removed startElement, Function<TokenRange, Boolean> hasOnlyWhitespaceFunction) { |
|
boolean hasOnlyWhitespace = false; |
|
if (startElement.isChild()) { |
|
LexicalDifferenceCalculator.CsmChild csmChild = (LexicalDifferenceCalculator.CsmChild) startElement.getElement(); |
|
Node child = csmChild.getChild(); |
|
|
|
Optional<TokenRange> tokenRange = child.getTokenRange(); |
|
if (tokenRange.isPresent()) { |
|
hasOnlyWhitespace = hasOnlyWhitespaceFunction.apply(tokenRange.get()); |
|
} |
|
} else if (startElement.isToken()) { |
|
CsmToken token = (CsmToken) startElement.getElement(); |
|
if (TokenTypes.isEndOfLineToken(token.getTokenType())) { |
|
hasOnlyWhitespace = true; |
|
} |
|
} |
|
return hasOnlyWhitespace; |
|
} |
|
|
|
private boolean hasOnlyWhiteSpaceForTokenFunction(JavaToken token, Function<JavaToken, Optional<JavaToken>> tokenFunction) { |
|
Optional<JavaToken> tokenResult = tokenFunction.apply(token); |
|
|
|
if (tokenResult.isPresent()) { |
|
if (TokenTypes.isWhitespaceButNotEndOfLine(tokenResult.get().getKind())) { |
|
return hasOnlyWhiteSpaceForTokenFunction(tokenResult.get(), tokenFunction); |
|
} else if (TokenTypes.isEndOfLineToken(tokenResult.get().getKind())) { |
|
return true; |
|
} else { |
|
return false; |
|
} |
|
} |
|
|
|
return true; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
final Optional<Integer> getIndentation() { |
|
Removed firstElement = getFirstElement(); |
|
|
|
int indentation = 0; |
|
if (firstElement.isChild()) { |
|
LexicalDifferenceCalculator.CsmChild csmChild = (LexicalDifferenceCalculator.CsmChild) firstElement.getElement(); |
|
Node child = csmChild.getChild(); |
|
|
|
Optional<TokenRange> tokenRange = child.getTokenRange(); |
|
if (tokenRange.isPresent()) { |
|
JavaToken begin = tokenRange.get().getBegin(); |
|
|
|
if (hasOnlyWhitespaceJavaTokenInFrontFunction.apply(begin)) { |
|
Optional<JavaToken> previousToken = begin.getPreviousToken(); |
|
|
|
while(previousToken.isPresent() && (TokenTypes.isWhitespaceButNotEndOfLine(previousToken.get().getKind()))) { |
|
indentation++; |
|
|
|
previousToken = previousToken.get().getPreviousToken(); |
|
} |
|
|
|
if (previousToken.isPresent()) { |
|
if (TokenTypes.isEndOfLineToken(previousToken.get().getKind())) { |
|
return Optional.of(Integer.valueOf(indentation)); |
|
} else { |
|
return Optional.empty(); |
|
} |
|
} else { |
|
return Optional.of(Integer.valueOf(indentation)); |
|
} |
|
} |
|
} |
|
} |
|
|
|
return Optional.empty(); |
|
} |
|
|
|
@Override |
|
public final Iterator<Removed> iterator() { |
|
return new Iterator<Removed>() { |
|
private int currentIndex = 0; |
|
|
|
@Override |
|
public boolean hasNext() { |
|
return currentIndex < removedList.size() && removedList.get(currentIndex) != null; |
|
} |
|
|
|
@Override |
|
public Removed next() { |
|
return removedList.get(currentIndex++); |
|
} |
|
|
|
}; |
|
} |
|
} |