Skip to content

Commit

Permalink
Merge pull request #4134 from jlerbsc/lookhead
Browse files Browse the repository at this point in the history
Minor refactoring: Simplifies how to group deleted tokens by extracting a method into an independent class
  • Loading branch information
jlerbsc committed Aug 30, 2023
2 parents 7f85786 + e9103d7 commit d087f19
Show file tree
Hide file tree
Showing 13 changed files with 699 additions and 331 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.github.javaparser.printer.lexicalpreservation;

import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;

import org.junit.jupiter.api.*;

class PeekingIteratorTest {

private static final List<String> EMPTY_LIST = new ArrayList();

private static List<String> NON_EMPTY_LIST ;

private PeekingIterator<String> peekingIterator;

@BeforeAll
static void setUpBeforeClass() throws Exception {
}

@AfterAll
static void tearDownAfterClass() throws Exception {
}

@BeforeEach
void setUp() throws Exception {
NON_EMPTY_LIST = Arrays.asList("A", "B", "C");
}

@AfterEach
void tearDown() throws Exception {
}

@Test
void testHasNext() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertFalse(peekingIterator.hasNext());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertTrue(peekingIterator.hasNext());
}

@Test
void testPeek() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertEquals(null, peekingIterator.peek());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertEquals("A", peekingIterator.peek());
assertEquals("A", peekingIterator.next());
}

@Test
void testElement() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertEquals(null, peekingIterator.peek());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertEquals("A", peekingIterator.peek());
assertEquals(1, peekingIterator.nextIndex());
}

@Test
void testNext() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertThrows(NoSuchElementException.class, () -> peekingIterator.next());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertEquals("A", peekingIterator.next());
}

@Test
void testRemove() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertThrows(IllegalStateException.class, () -> peekingIterator.remove());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertThrows(IllegalStateException.class, () -> peekingIterator.remove());
String result = peekingIterator.next();
assertThrows(UnsupportedOperationException.class, () -> peekingIterator.remove());
}

@Test
void testHasPrevious() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertFalse(peekingIterator.hasPrevious());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertFalse(peekingIterator.hasPrevious());
String result = peekingIterator.next();
assertTrue(peekingIterator.hasPrevious());
}

@Test
void testPrevious() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertThrows(NoSuchElementException.class, () -> peekingIterator.previous());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertThrows(NoSuchElementException.class, () -> peekingIterator.previous());
}

@Test
void testNextIndex() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertEquals(0, peekingIterator.nextIndex());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertEquals(0, peekingIterator.nextIndex());
}

@Test
void testPreviousIndex() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertEquals(-1, peekingIterator.previousIndex());
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertEquals(-1, peekingIterator.previousIndex());
}

@Test
void testSet() {
peekingIterator = new PeekingIterator(EMPTY_LIST.listIterator());
assertThrows(IllegalStateException.class, () -> peekingIterator.set("D"));
peekingIterator = new PeekingIterator(NON_EMPTY_LIST.listIterator());
assertThrows(IllegalStateException.class, () -> peekingIterator.set("D"));
peekingIterator.next();
peekingIterator.set("D");
assertEquals(3, NON_EMPTY_LIST.size());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@
*/
package com.github.javaparser.printer.concretesyntaxmodel;

import static com.github.javaparser.TokenTypes.eolTokenKind;
import static com.github.javaparser.TokenTypes.spaceTokenKind;

import java.util.Arrays;
import java.util.List;

import com.github.javaparser.GeneratedJavaParserConstants;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.observer.ObservableProperty;
import com.github.javaparser.printer.SourcePrinter;
import com.github.javaparser.printer.lexicalpreservation.TextElement;
import com.github.javaparser.utils.LineSeparator;

import java.util.Arrays;
import java.util.List;

import static com.github.javaparser.TokenTypes.eolTokenKind;
import static com.github.javaparser.TokenTypes.spaceTokenKind;

public interface CsmElement {

void prettyPrint(Node node, SourcePrinter printer);
Expand Down Expand Up @@ -72,10 +73,6 @@ static CsmElement token(int tokenType) {
return new CsmToken(tokenType);
}

static CsmElement token(int tokenType, CsmToken.TokenContentCalculator tokenContentCalculator) {
return new CsmToken(tokenType, tokenContentCalculator);
}

static CsmElement conditional(ObservableProperty property, CsmConditional.Condition condition, CsmElement thenElement) {
return new CsmConditional(property, condition, thenElement);
}
Expand Down Expand Up @@ -152,4 +149,11 @@ static CsmElement unindent() {
static CsmElement block(CsmElement content) {
return sequence(token(GeneratedJavaParserConstants.LBRACE), indent(), content, unindent(), token(GeneratedJavaParserConstants.RBRACE));
}

/*
* Verifies if the content of the {@code CsmElement} is the same as the provided {@code TextElement}
*/
default boolean isCorrespondingElement(TextElement textElement) {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

import com.github.javaparser.ast.Node;
import com.github.javaparser.printer.SourcePrinter;
import com.github.javaparser.printer.lexicalpreservation.TextElement;
import com.github.javaparser.printer.lexicalpreservation.TokenTextElement;

public class CsmIndent implements CsmElement {

Expand All @@ -30,6 +32,15 @@ public void prettyPrint(Node node, SourcePrinter printer) {
printer.indent();
}

/*
* Verifies if the content of the {@code CsmElement} is the same as the provided {@code TextElement}
*/
@Override
public boolean isCorrespondingElement(TextElement textElement) {
return (textElement instanceof TokenTextElement)
&& ((TokenTextElement)textElement).isSpaceOrTab();
}

@Override
public int hashCode() {
return 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,28 @@
*/
package com.github.javaparser.printer.concretesyntaxmodel;

import static com.github.javaparser.TokenTypes.isEndOfLineToken;
import static com.github.javaparser.TokenTypes.isWhitespaceButNotEndOfLine;

import com.github.javaparser.GeneratedJavaParserConstants;
import com.github.javaparser.TokenTypes;
import com.github.javaparser.ast.Node;
import com.github.javaparser.printer.SourcePrinter;
import com.github.javaparser.printer.lexicalpreservation.TextElement;
import com.github.javaparser.printer.lexicalpreservation.TokenTextElement;
import com.github.javaparser.utils.LineSeparator;

import static com.github.javaparser.TokenTypes.isEndOfLineToken;
import static com.github.javaparser.TokenTypes.isWhitespaceButNotEndOfLine;

public class CsmToken implements CsmElement {

private final int tokenType;

private String content;

private TokenContentCalculator tokenContentCalculator;

public interface TokenContentCalculator {

String calculate(Node node);
}

public int getTokenType() {
return tokenType;
}

public String getContent(Node node) {
if (tokenContentCalculator != null) {
return tokenContentCalculator.calculate(node);
}
public String getContent() {
return content;
}

Expand All @@ -74,17 +66,12 @@ public CsmToken(int tokenType, String content) {
this.content = content;
}

public CsmToken(int tokenType, TokenContentCalculator tokenContentCalculator) {
this.tokenType = tokenType;
this.tokenContentCalculator = tokenContentCalculator;
}

@Override
public void prettyPrint(Node node, SourcePrinter printer) {
if (isEndOfLineToken(tokenType)) {
printer.println();
} else {
printer.print(getContent(node));
printer.print(getContent());
}
}

Expand All @@ -104,26 +91,35 @@ public boolean equals(Object o) {
return false;
if (content != null ? !content.equals(csmToken.content) : csmToken.content != null)
return false;
return tokenContentCalculator != null ? tokenContentCalculator.equals(csmToken.tokenContentCalculator) : csmToken.tokenContentCalculator == null;
return true;
}

@Override
public int hashCode() {
int result = tokenType;
result = 31 * result + (content != null ? content.hashCode() : 0);
result = 31 * result + (tokenContentCalculator != null ? tokenContentCalculator.hashCode() : 0);
return result;
}

public boolean isWhiteSpace() {
return TokenTypes.isWhitespace(tokenType);
}

public boolean isWhiteSpaceNotEol() {
return isWhiteSpace() && !isNewLine();
}

public boolean isNewLine() {
return TokenTypes.isEndOfLineToken(tokenType);
}

/*
* Verifies if the content of the {@code CsmElement} is the same as the provided {@code TextElement}
*/
@Override
public boolean isCorrespondingElement(TextElement textElement) {
return (textElement instanceof TokenTextElement)
&& ((TokenTextElement)textElement).getTokenKind() == getTokenType()
&& ((TokenTextElement)textElement).getText().equals(getContent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public TextElement toTextElement() {
return new ChildTextElement(((LexicalDifferenceCalculator.CsmChild) element).getChild());
}
if (element instanceof CsmToken) {
return new TokenTextElement(((CsmToken) element).getTokenType(), ((CsmToken) element).getContent(null));
return new TokenTextElement(((CsmToken) element).getTokenType(), ((CsmToken) element).getContent());
}
throw new UnsupportedOperationException(element.getClass().getSimpleName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,39 @@
*/
package com.github.javaparser.printer.lexicalpreservation;

import java.util.Optional;

import com.github.javaparser.Range;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.comments.Comment;

import java.util.Optional;

/**
* Represent the position of a child node in the NodeText of its parent.
*/
class ChildTextElement extends TextElement {
public class ChildTextElement extends TextElement {

private final Node child;

ChildTextElement(Node child) {
this.child = child;
}

String expand() {
@Override
public String expand() {
return LexicalPreservingPrinter.print(child);
}

Node getChild() {
public Node getChild() {
return child;
}

@Override
boolean isToken(int tokenKind) {
public boolean isToken(int tokenKind) {
return false;
}

@Override
boolean isNode(Node node) {
public boolean isNode(Node node) {
return node == child;
}

Expand Down

0 comments on commit d087f19

Please sign in to comment.