Skip to content

Commit

Permalink
Merge pull request #3704 from jlerbsc/master
Browse files Browse the repository at this point in the history
Fix issue #3700 Removing last statement with LexicalPreservingPrinter results in loss of indendation
  • Loading branch information
jlerbsc committed Sep 20, 2022
2 parents 69fabda + e01e12c commit 0547901
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@

package com.github.javaparser.printer.lexicalpreservation;

import static com.github.javaparser.ast.Modifier.Keyword.STATIC;
import static com.github.javaparser.utils.TestUtils.assertEqualsStringIgnoringEol;
import static com.github.javaparser.utils.Utils.SYSTEM_EOL;

import java.io.IOException;

import org.junit.jupiter.api.Test;

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
Expand All @@ -35,13 +43,6 @@
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.type.ArrayType;
import com.github.javaparser.ast.type.PrimitiveType;
import org.junit.jupiter.api.Test;

import java.io.IOException;

import static com.github.javaparser.ast.Modifier.Keyword.STATIC;
import static com.github.javaparser.utils.TestUtils.assertEqualsStringIgnoringEol;
import static com.github.javaparser.utils.Utils.SYSTEM_EOL;

/**
* These tests are more "high level" than the ones in LexicalPreservingPrinterTest.
Expand Down Expand Up @@ -166,7 +167,9 @@ void exampleParam5() throws IOException {
md.setType(PrimitiveType.intType());
assertTransformed("Example_param5b", cu);
md.getBody().get().getStatements().add(new ReturnStmt(new NameExpr("p1")));
assertTransformed("Example_param5", cu);
String expected = readExample("Example_param5" + "_expected");
String s = LexicalPreservingPrinter.print(cu);
assertEqualsStringIgnoringEol(expected, s);
}

@Test
Expand Down Expand Up @@ -307,4 +310,36 @@ void addingStatement3() {
"}";
assertEqualsStringIgnoringEol(expected, s);
}

@Test
void removingInSingleMemberList() {
considerCode(
"class A {\n" +
" int a;\n" +
"}");
cu.getClassByName("A").get().getMembers().remove(0);
String expected =
"class A {\n" +
"}";
String s = LexicalPreservingPrinter.print(cu);
assertEqualsStringIgnoringEol(expected, s);
}

@Test
void removingInMultiMembersList() {
considerCode(
"class A {\n" +
" int a;\n" +
" int b;\n" +
"}");
cu.getClassByName("A").get().getMembers().removeLast();
String expected =
"class A {\n" +
" int a;\n" +
"}";
String s = LexicalPreservingPrinter.print(cu);
assertEqualsStringIgnoringEol(expected, s);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -564,16 +564,8 @@ private void applyKeptDiffElement(Kept kept, TextElement originalElement, boolea
} else if (kept.isIndent()) {
diffIndex++;
} else if (kept.isUnindent()) {
// Nothing to do, beside considering indentation
// However we want to consider the case in which the indentation was not applied, like when we have
// just a left brace followed by space

// Nothing to do
diffIndex++;
if (!openBraceWasOnSameLine()) {
for (int i = 0; i < STANDARD_INDENTATION_SIZE && originalIndex >= 1 && nodeText.getTextElement(originalIndex - 1).isSpaceOrTab(); i++) {
nodeText.removeElement(--originalIndex);
}
}
} else {
throw new UnsupportedOperationException("kept " + kept.getElement() + " vs " + originalElement);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@

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;

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;

/**
* This class represents a group of {@link Removed} elements.
* The {@link Removed} elements are ideally consecutive for the methods in this class to work correctly.
Expand Down Expand Up @@ -187,14 +187,30 @@ private boolean hasOnlyWhiteSpaceForTokenFunction(JavaToken token, Function<Java

/**
* Returns the indentation in front of this RemovedGroup if possible.
* If there is something else than whitespace in front, Optional.empty() is returned.
* Sometimes the first deleted element may be a line break because the <code>ConcreteSyntaxModel</code> generates a line break before the members (for example FieldDeclaration).
* In this case a remove operation on the member will generate the deletion of the first line break.
* It is therefore necessary to avoid taking this element into account so we're looking for the first element that isn't a line break..
* For example
* class Foo {
* int x;
* }
* If there is something else than whitespace in front this element, Optional.empty() is returned.
*
* @return the indentation in front of this RemovedGroup or Optional.empty()
*/
final Optional<Integer> getIndentation() {
Removed firstElement = getFirstElement();

Removed firstElement = null;
int indentation = 0;

// search for the first element which is not a new line
Iterator it = iterator();
while(it.hasNext() ) {
firstElement = (Removed) it.next();
if (firstElement.isNewLine())
continue;
break;
}

if (firstElement.isChild()) {
LexicalDifferenceCalculator.CsmChild csmChild = (LexicalDifferenceCalculator.CsmChild) firstElement.getElement();
Node child = csmChild.getChild();
Expand Down

0 comments on commit 0547901

Please sign in to comment.