JavaParser Source Viewer

Home|JavaParser/com/github/javaparser/ast/NodeList.java
1/*
2 * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2020 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
22package com.github.javaparser.ast;
23
24import com.github.javaparser.HasParentNode;
25import com.github.javaparser.ast.observer.AstObserver;
26import com.github.javaparser.ast.observer.Observable;
27import com.github.javaparser.ast.visitor.GenericVisitor;
28import com.github.javaparser.ast.visitor.Visitable;
29import com.github.javaparser.ast.visitor.VoidVisitor;
30import com.github.javaparser.metamodel.InternalProperty;
31
32import java.util.*;
33import java.util.function.Consumer;
34import java.util.function.Predicate;
35import java.util.function.UnaryOperator;
36import java.util.stream.Collector;
37import java.util.stream.Collectors;
38import java.util.stream.Stream;
39
40/**
41 * A list of nodes.
42 * It usually has a parent node.
43 * Unlike normal Nodes, this does not mean that it is a child of that parent.
44 * Instead, this list will make every node it contains a child of its parent.
45 * This way, a NodeList does not create an extra level inside the AST.
46 *
47 * @param <N> the type of nodes contained.
48 */
49public class NodeList<N extends Node> implements List<N>, Iterable<N>, HasParentNode<NodeList<N>>, VisitableObservable {
50    @InternalProperty
51    private List<NinnerList = new ArrayList<>(0);
52
53    private Node parentNode;
54
55    private List<AstObserverobservers = new ArrayList<>();
56
57    public NodeList() {
58        parentNode = null;
59    }
60
61    public NodeList(Collection<Nn) {
62        this.addAll(n);
63    }
64
65    @SafeVarargs
66    public NodeList(N... n) {
67        this.addAll(Arrays.asList(n));
68    }
69
70    @Override
71    public boolean add(N node) {
72        notifyElementAdded(innerList.size(), node);
73        own(node);
74        return innerList.add(node);
75    }
76
77    private void own(N node) {
78        if (node == null) {
79            return;
80        }
81        setAsParentNodeOf(node);
82    }
83
84    public boolean remove(Node node) {
85        int index = innerList.indexOf(node);
86        if (index != -1) {
87            notifyElementRemoved(indexnode);
88            node.setParentNode(null);
89        }
90        return innerList.remove(node);
91    }
92
93    public N removeFirst() {
94        return remove(0);
95    }
96
97    public N removeLast() {
98        return remove(innerList.size() - 1);
99    }
100
101    @SafeVarargs
102    public static <X extends NodeNodeList<XnodeList(X... nodes) {
103        final NodeList<XnodeList = new NodeList<>();
104        Collections.addAll(nodeListnodes);
105        return nodeList;
106    }
107
108    public static <X extends NodeNodeList<XnodeList(Collection<Xnodes) {
109        final NodeList<XnodeList = new NodeList<>();
110        nodeList.addAll(nodes);
111        return nodeList;
112    }
113
114    public static <X extends NodeNodeList<XnodeList(NodeList<Xnodes) {
115        final NodeList<XnodeList = new NodeList<>();
116        nodeList.addAll(nodes);
117        return nodeList;
118    }
119
120    public boolean contains(N node) {
121        return innerList.contains(node);
122    }
123
124    @Override
125    public int size() {
126        return innerList.size();
127    }
128
129    @Override
130    public N get(int i) {
131        return innerList.get(i);
132    }
133
134    @Override
135    public Iterator<Niterator() {
136        // TODO take care of "Iterator.remove"
137        return innerList.iterator();
138    }
139
140    @Override
141    public N set(int indexN element) {
142        if (index < 0 || index >= innerList.size()) {
143            throw new IllegalArgumentException("Illegal index. The index should be between 0 and " + innerList.size()
144                    + " excluded. It is instead " + index);
145        }
146        if (element == innerList.get(index)) {
147            return element;
148        }
149        notifyElementReplaced(indexelement);
150        innerList.get(index).setParentNode(null);
151        setAsParentNodeOf(element);
152        return innerList.set(indexelement);
153    }
154
155    @Override
156    public N remove(int index) {
157        notifyElementRemoved(indexinnerList.get(index));
158        N remove = innerList.remove(index);
159        if (remove != null)
160            remove.setParentNode(null);
161        return remove;
162    }
163
164    @Override
165    public boolean isEmpty() {
166        return innerList.isEmpty();
167    }
168
169    @Override
170    public void sort(Comparator<? super Ncomparator) {
171        innerList.sort(comparator);
172    }
173
174    public void addAll(NodeList<NotherList) {
175        for (N node : otherList) {
176            add(node);
177        }
178    }
179
180    @Override
181    public void add(int indexN node) {
182        notifyElementAdded(indexnode);
183        own(node);
184        innerList.add(indexnode);
185    }
186
187    /**
188     * Inserts the node before all other nodes.
189     */
190    public NodeList<NaddFirst(N node) {
191        add(0node);
192        return this;
193    }
194
195    /**
196     * Inserts the node after all other nodes. (This is simply an alias for add.)
197     */
198    public NodeList<NaddLast(N node) {
199        add(node);
200        return this;
201    }
202
203    /**
204     * Inserts the node after afterThisNode.
205     *
206     * @throws IllegalArgumentException when afterThisNode is not in this list.
207     */
208    public NodeList<NaddAfter(N nodeN afterThisNode) {
209        int i = indexOf(afterThisNode);
210        if (i == -1) {
211            throw new IllegalArgumentException("Can't find node to insert after.");
212        }
213        add(i + 1node);
214        return this;
215    }
216
217    /**
218     * Inserts the node before beforeThisNode.
219     *
220     * @throws IllegalArgumentException when beforeThisNode is not in this list.
221     */
222    public NodeList<NaddBefore(N nodeN beforeThisNode) {
223        int i = indexOf(beforeThisNode);
224        if (i == -1) {
225            throw new IllegalArgumentException("Can't find node to insert before.");
226        }
227        add(inode);
228        return this;
229    }
230
231
232    /**
233     * @return the first node, or empty if the list is empty.
234     */
235    public Optional<NgetFirst() {
236        if (isEmpty()) {
237            return Optional.empty();
238        }
239        return Optional.of(get(0));
240    }
241
242    /**
243     * @return the last node, or empty if the list is empty.
244     */
245    public Optional<NgetLast() {
246        if (isEmpty()) {
247            return Optional.empty();
248        }
249        return Optional.of(get(size() - 1));
250    }
251
252    @Override
253    public Optional<NodegetParentNode() {
254        return Optional.ofNullable(parentNode);
255    }
256
257    /**
258     * Sets the parentNode
259     *
260     * @param parentNode the parentNode
261     * @return this, the NodeList
262     */
263    @Override
264    public NodeList<NsetParentNode(Node parentNode) {
265        this.parentNode = parentNode;
266        setAsParentNodeOf(innerList);
267        return this;
268    }
269
270    @Override
271    public Node getParentNodeForChildren() {
272        return parentNode;
273    }
274
275    @Override
276    public <RAR accept(final GenericVisitor<RAvfinal A arg) {
277        return v.visit(this, arg);
278    }
279
280    @Override
281    public <Avoid accept(final VoidVisitor<Avfinal A arg) {
282        v.visit(this, arg);
283    }
284
285    /**
286     * @see java.lang.Iterable#forEach(java.util.function.Consumer)
287     */
288    @Override
289    public void forEach(Consumer<? super Naction) {
290        innerList.forEach(action);
291    }
292
293    /**
294     * @see java.util.List#contains(java.lang.Object)
295     */
296    @Override
297    public boolean contains(Object o) {
298        return innerList.contains(o);
299    }
300
301    /**
302     * @see java.util.List#toArray()
303     */
304    @Override
305    public Object[] toArray() {
306        return innerList.toArray();
307    }
308
309    /**
310     * @see java.util.List#toArray(java.lang.Object[])
311     */
312    @Override
313    public <TT[] toArray(T[] a) {
314        return innerList.toArray(a);
315    }
316
317    /**
318     * @see java.util.List#remove(java.lang.Object)
319     */
320    @Override
321    public boolean remove(Object o) {
322        if (o instanceof Node) {
323            return remove((Nodeo);
324        } else {
325            return false;
326        }
327    }
328
329    /**
330     * @see java.util.List#containsAll(java.util.Collection)
331     */
332    @Override
333    public boolean containsAll(Collection<?> c) {
334        return innerList.containsAll(c);
335    }
336
337    /**
338     * @see java.util.List#addAll(java.util.Collection)
339     */
340    @Override
341    public boolean addAll(Collection<? extends Nc) {
342        c.forEach(this::add);
343        return !c.isEmpty();
344    }
345
346    /**
347     * @see java.util.List#addAll(int, java.util.Collection)
348     */
349    @Override
350    public boolean addAll(int indexCollection<? extends Nc) {
351        for (N e : c) {
352            add(index++, e);
353        }
354        return !c.isEmpty();
355    }
356
357    /**
358     * @see java.util.List#removeAll(java.util.Collection)
359     */
360    @Override
361    public boolean removeAll(Collection<?> c) {
362        boolean changed = false;
363        for (Object e : c) {
364            changed = remove(e) || changed;
365        }
366        return changed;
367    }
368
369    /**
370     * @see java.util.List#retainAll(java.util.Collection)
371     */
372    @Override
373    public boolean retainAll(Collection<?> c) {
374        boolean changed = false;
375        for (Object e : this.stream().filter(it -> !c.contains(it)).toArray()) {
376            if (!c.contains(e)) {
377                changed = remove(e) || changed;
378            }
379        }
380        return changed;
381    }
382
383    /**
384     * @see java.util.List#replaceAll(java.util.function.UnaryOperator)
385     */
386    @Override
387    public void replaceAll(UnaryOperator<Noperator) {
388        for (int i = 0i < this.size(); i++) {
389            set(ioperator.apply(this.get(i)));
390        }
391    }
392
393    /**
394     * @see java.util.Collection#removeIf(java.util.function.Predicate)
395     */
396    @Override
397    public boolean removeIf(Predicate<? super Nfilter) {
398        boolean changed = false;
399        for (Object e : this.stream().filter(filter).toArray()) {
400            changed = remove(e) || changed;
401        }
402        return changed;
403    }
404
405    /**
406     * @see java.util.List#clear()
407     */
408    @Override
409    public void clear() {
410        while (!isEmpty()) {
411            remove(0);
412        }
413    }
414
415    /**
416     * @see java.util.List#equals(java.lang.Object)
417     */
418    @Override
419    public boolean equals(Object o) {
420        return innerList.equals(o);
421    }
422
423    /**
424     * @see java.util.List#hashCode()
425     */
426    @Override
427    public int hashCode() {
428        return innerList.hashCode();
429    }
430
431    /**
432     * @see java.util.List#indexOf(java.lang.Object)
433     */
434    @Override
435    public int indexOf(Object o) {
436        return innerList.indexOf(o);
437    }
438
439    /**
440     * @see java.util.List#lastIndexOf(java.lang.Object)
441     */
442    @Override
443    public int lastIndexOf(Object o) {
444        return innerList.lastIndexOf(o);
445    }
446
447    /**
448     * @see java.util.List#listIterator()
449     */
450    @Override
451    public ListIterator<NlistIterator() {
452        return innerList.listIterator();
453    }
454
455    /**
456     * @see java.util.List#listIterator(int)
457     */
458    @Override
459    public ListIterator<NlistIterator(int index) {
460        return innerList.listIterator(index);
461    }
462
463    /**
464     * @see java.util.Collection#parallelStream()
465     */
466    @Override
467    public Stream<NparallelStream() {
468        return innerList.parallelStream();
469    }
470
471    /**
472     * @see java.util.List#subList(int, int)
473     */
474    @Override
475    public List<NsubList(int fromIndexint toIndex) {
476        return innerList.subList(fromIndextoIndex);
477    }
478
479    /**
480     * @see java.util.List#spliterator()
481     */
482    @Override
483    public Spliterator<Nspliterator() {
484        return innerList.spliterator();
485    }
486
487    private void notifyElementAdded(int indexNode nodeAddedOrRemoved) {
488        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.ADDITIONindexnodeAddedOrRemoved));
489    }
490
491    private void notifyElementRemoved(int indexNode nodeAddedOrRemoved) {
492        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.REMOVALindexnodeAddedOrRemoved));
493    }
494
495    private void notifyElementReplaced(int indexNode nodeAddedOrRemoved) {
496        this.observers.forEach(o -> o.listReplacement(this, index, this.get(index), nodeAddedOrRemoved));
497    }
498
499    @Override
500    public void unregister(AstObserver observer) {
501        this.observers.remove(observer);
502    }
503
504    @Override
505    public void register(AstObserver observer) {
506        if (!this.observers.contains(observer)) {
507            this.observers.add(observer);
508        }
509    }
510
511    @Override
512    public boolean isRegistered(AstObserver observer) {
513        return this.observers.contains(observer);
514    }
515
516    /**
517     * Replaces the first node that is equal to "old" with "replacement".
518     *
519     * @return true if a replacement has happened.
520     */
521    public boolean replace(N oldN replacement) {
522        int i = indexOf(old);
523        if (i == -1) {
524            return false;
525        }
526        set(ireplacement);
527        return true;
528    }
529
530    /**
531     * @return the opposite of isEmpty()
532     */
533    public boolean isNonEmpty() {
534        return !isEmpty();
535    }
536
537    public void ifNonEmpty(Consumer<? super NodeList<N>> consumer) {
538        if (isNonEmpty())
539            consumer.accept(this);
540    }
541
542    public static <T extends NodeCollector<TNodeList<T>, NodeList<T>> toNodeList() {
543        return Collector.of(NodeList::new, NodeList::add, (leftright) -> {
544            left.addAll(right);
545            return left;
546        });
547    }
548
549    private void setAsParentNodeOf(List<? extends NodechildNodes) {
550        if (childNodes != null) {
551            for (HasParentNode current : childNodes) {
552                current.setParentNode(getParentNodeForChildren());
553            }
554        }
555    }
556
557    private void setAsParentNodeOf(Node childNode) {
558        if (childNode != null) {
559            childNode.setParentNode(getParentNodeForChildren());
560        }
561    }
562
563    @Override
564    public String toString() {
565        return innerList.stream().map(Node::toString).collect(Collectors.joining(", ""[""]"));
566    }
567}
568
MembersX
NodeList:accept
NodeList:replaceAll
NodeList:isNonEmpty
NodeList:isEmpty
NodeList:toArray
NodeList:unregister
NodeList:lastIndexOf
NodeList:toString
NodeList:remove:Block:remove
NodeList:set
NodeList:addBefore
NodeList:contains
NodeList:clear
NodeList:notifyElementRemoved
NodeList:nodeList:Block:nodeList
NodeList:get
NodeList:getParentNodeForChildren
NodeList:containsAll
NodeList:getLast
NodeList:register
NodeList:sort
NodeList:equals
NodeList:removeAll:Block:changed
NodeList:parallelStream
NodeList:addBefore:Block:i
NodeList:getParentNode
NodeList:iterator
NodeList:addAll
NodeList:addAfter
NodeList:retainAll:Block:changed
NodeList:getFirst
NodeList:hashCode
NodeList:spliterator
NodeList:setAsParentNodeOf
NodeList:setParentNode
NodeList:subList
NodeList:remove:Block:index
NodeList:replace:Block:i
NodeList:size
NodeList:removeIf:Block:changed
NodeList:forEach
NodeList:add
NodeList:replace
NodeList:notifyElementReplaced
NodeList:indexOf
NodeList:addFirst
NodeList:addLast
NodeList:toNodeList
NodeList:remove
NodeList:removeAll
NodeList:removeFirst
NodeList:ifNonEmpty
NodeList:observers
NodeList:retainAll
NodeList:own
NodeList:innerList
NodeList:NodeList
NodeList:notifyElementAdded
NodeList:removeLast
NodeList:parentNode
NodeList:removeIf
NodeList:nodeList
NodeList:addAfter:Block:i
NodeList:listIterator
NodeList:isRegistered
Members
X