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