1de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti/* 2de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * Copyright (C) 2007-2010 Júlio Vilmar Gesser. 3de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * Copyright (C) 2011, 2013-2016 The JavaParser Team. 4de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * 5de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * This file is part of JavaParser. 6de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * 7de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * JavaParser can be used either under the terms of 8de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * a) the GNU Lesser General Public License as published by 9de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * the Free Software Foundation, either version 3 of the License, or 10de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * (at your option) any later version. 11de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * b) the terms of the Apache License 12de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * 13de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * You should have received a copy of both licenses in LICENCE.LGPL and 14de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * LICENCE.APACHE. Please refer to those files for details. 15de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * 16de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * JavaParser is distributed in the hope that it will be useful, 17de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * but WITHOUT ANY WARRANTY; without even the implied warranty of 18de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti * GNU Lesser General Public License for more details. 20de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti */ 21de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 22de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassettipackage com.github.javaparser.printer.lexicalpreservation; 23de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 24de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassettiimport java.util.Iterator; 25de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassettiimport java.util.LinkedList; 26de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassettiimport java.util.List; 27de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 28b83b81211f26f9259b032b188bb2482aa390df0dFederico Tomassetticlass TextElementIteratorsFactory { 29de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 30de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti static class CascadingIterator<E> implements Iterator<E> { 31de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti interface Provider<E> { 32de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti Iterator<E> provide(); 33de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 34de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 35b83b81211f26f9259b032b188bb2482aa390df0dFederico Tomassetti private final Provider<E> nextProvider; 36de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti private Iterator<E> current; 37dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti private Iterator<E> next; 38dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti private boolean lastReturnedFromCurrent = false; 39dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti private boolean lastReturnedFromNext = false; 40de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 41de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public CascadingIterator(Iterator<E> current, Provider<E> nextProvider) { 42de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti this.nextProvider = nextProvider; 43de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti this.current = current; 44de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 45de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 46de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 47de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 48de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public boolean hasNext() { 49de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti if (current.hasNext()) { 50de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return true; 51de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 52de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti if (next == null) { 53de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti next = nextProvider.provide(); 54de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 55de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return next.hasNext(); 56de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 57de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 58de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 59de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public E next() { 60de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti if (current.hasNext()) { 61dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti lastReturnedFromCurrent = true; 62dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti lastReturnedFromNext = false; 63de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return current.next(); 64de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 65de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti if (next == null) { 66de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti next = nextProvider.provide(); 67de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 68dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti lastReturnedFromCurrent = false; 69dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti lastReturnedFromNext = true; 70de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return next.next(); 71de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 72dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti 73dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti @Override 74dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti public void remove() { 75dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti if (lastReturnedFromCurrent) { 76dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti current.remove(); 77dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti return; 78dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti } 79dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti if (lastReturnedFromNext) { 80dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti next.remove(); 81dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti return; 82dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti } 83dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti throw new IllegalArgumentException(); 84dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti } 85de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 86de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 87de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti static class EmptyIterator<E> implements Iterator<E> { 88de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 89de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public boolean hasNext() { 90de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return false; 91de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 92de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 93de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 94de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public E next() { 95de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti throw new IllegalArgumentException(); 96de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 97de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 98de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 99de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti private static class SingleElementIterator<E> implements Iterator<E> { 100b83b81211f26f9259b032b188bb2482aa390df0dFederico Tomassetti private final E element; 101de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti private boolean returned; 102de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 103de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti SingleElementIterator(E element) { 104de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti this.element = element; 105de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 106de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 107de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 108de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public boolean hasNext() { 109de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return !returned; 110de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 111de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 112de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 113de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public E next() { 114de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti returned = true; 115de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return element; 116de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 117dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti 118dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti @Override 119dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti public void remove() { 120dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti 121dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti } 122de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 123de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 124de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti static class ComposedIterator<E> implements Iterator<E> { 125b83b81211f26f9259b032b188bb2482aa390df0dFederico Tomassetti private final List<Iterator<E>> elements; 126de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti private int currIndex; 127de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 128de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti ComposedIterator(List<Iterator<E>> elements) { 129de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti this.elements = elements; 130de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti currIndex = 0; 131de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 132de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 133de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 134de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public boolean hasNext() { 135dec68cfc83301b4e7ee2bbf1886959d6aa05f85aFederico Tomassetti if (currIndex >= elements.size()) { 136de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return false; 137de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 138de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti if (elements.get(currIndex).hasNext()){ 139de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return true; 140de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 141dec68cfc83301b4e7ee2bbf1886959d6aa05f85aFederico Tomassetti currIndex++; 142de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return hasNext(); 143de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 144de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 145de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti @Override 146de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public E next() { 147de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti if (!hasNext()) { 148de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti throw new IllegalArgumentException(); 149de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 150de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return elements.get(currIndex).next(); 151de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 152dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti 153dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti @Override 154dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti public void remove() { 155dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti elements.get(currIndex).remove(); 156dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti } 157de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 158de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 159dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti private static Iterator<TokenTextElement> reverseIterator(NodeText nodeText, int index) { 160dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti TextElement textElement = nodeText.getTextElement(index); 161de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti if (textElement instanceof TokenTextElement) { 162dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti return new SingleElementIterator<TokenTextElement>((TokenTextElement)textElement) { 163dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti @Override 164dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti public void remove() { 165dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti nodeText.removeElement(index); 166dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti } 167dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti }; 168de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } else if (textElement instanceof ChildTextElement) { 169de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti ChildTextElement childTextElement = (ChildTextElement)textElement; 170de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti NodeText textForChild = childTextElement.getNodeTextForWrappedNode(); 171de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return reverseIterator(textForChild); 172de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } else { 173de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti throw new IllegalArgumentException(); 174de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 175de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 176de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 177de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti public static Iterator<TokenTextElement> reverseIterator(NodeText nodeText) { 178dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti return partialReverseIterator(nodeText, nodeText.numberOfElements() - 1); 179de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 180de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 181dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti public static Iterator<TokenTextElement> partialReverseIterator(NodeText nodeText, int fromIndex) { 182de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti List<Iterator<TokenTextElement>> elements = new LinkedList<>(); 183de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti for (int i=fromIndex;i>=0;i--) { 184dea490b3c4b649d5ede5f12dbf6740b816681cf2Federico Tomassetti elements.add(reverseIterator(nodeText, i)); 185de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 186de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti return new ComposedIterator<>(elements); 187de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti } 188de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti 189de11a2ae80166defacd1f9c51b77f52be4b53eb1Federico Tomassetti} 190