PageRenderTime 38ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/javac_compiler/JavaSource/src/main/java/berlin/com/sun/tools/javac/util/List.java

http://jvmnotebook.googlecode.com/
Java | 476 lines | 317 code | 52 blank | 107 comment | 89 complexity | 92697f4d5fa119854471f5577a5273c6 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, Apache-2.0, CPL-1.0, AGPL-1.0, JSON, LGPL-2.1, GPL-2.0, BSD-3-Clause, BSD-3-Clause-No-Nuclear-License-2014, Unlicense, LGPL-2.0
  1. /*
  2. * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4. *
  5. * This code is free software; you can redistribute it and/or modify it
  6. * under the terms of the GNU General Public License version 2 only, as
  7. * published by the Free Software Foundation. Oracle designates this
  8. * particular file as subject to the "Classpath" exception as provided
  9. * by Oracle in the LICENSE file that accompanied this code.
  10. *
  11. * This code is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14. * version 2 for more details (a copy is included in the LICENSE file that
  15. * accompanied this code).
  16. *
  17. * You should have received a copy of the GNU General Public License version
  18. * 2 along with this work; if not, write to the Free Software Foundation,
  19. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22. * or visit www.oracle.com if you need additional information or have any
  23. * questions.
  24. */
  25. package berlin.com.sun.tools.javac.util;
  26. import java.lang.reflect.Array;
  27. import java.util.ArrayList;
  28. import java.util.Collection;
  29. import java.util.Collections;
  30. import java.util.Iterator;
  31. import java.util.AbstractCollection;
  32. import java.util.ListIterator;
  33. import java.util.NoSuchElementException;
  34. /** A class for generic linked lists. Links are supposed to be
  35. * immutable, the only exception being the incremental construction of
  36. * lists via ListBuffers. List is the main container class in
  37. * GJC. Most data structures and algorthms in GJC use lists rather
  38. * than arrays.
  39. */
  40. public class List<A> extends AbstractCollection<A> implements java.util.List<A> {
  41. /** The first element of the list, supposed to be immutable.
  42. */
  43. public A head;
  44. /** The remainder of the list except for its first element, supposed
  45. * to be immutable.
  46. */
  47. //@Deprecated
  48. public List<A> tail;
  49. /** Construct a list given its head and tail.
  50. */
  51. List(A head, List<A> tail) {
  52. this.tail = tail;
  53. this.head = head;
  54. }
  55. /** Construct an empty list.
  56. */
  57. @SuppressWarnings("unchecked")
  58. public static <A> List<A> nil() {
  59. return EMPTY_LIST;
  60. }
  61. private static List EMPTY_LIST = new List<Object>(null,null) {
  62. public List<Object> setTail(List<Object> tail) {
  63. throw new UnsupportedOperationException();
  64. }
  65. public boolean isEmpty() {
  66. return true;
  67. }
  68. };
  69. /** Construct a list consisting of given element.
  70. */
  71. public static <A> List<A> of(A x1) {
  72. return new List<A>(x1, List.<A>nil());
  73. }
  74. /** Construct a list consisting of given elements.
  75. */
  76. public static <A> List<A> of(A x1, A x2) {
  77. return new List<A>(x1, of(x2));
  78. }
  79. /** Construct a list consisting of given elements.
  80. */
  81. public static <A> List<A> of(A x1, A x2, A x3) {
  82. return new List<A>(x1, of(x2, x3));
  83. }
  84. /** Construct a list consisting of given elements.
  85. */
  86. public static <A> List<A> of(A x1, A x2, A x3, A... rest) {
  87. return new List<A>(x1, new List<A>(x2, new List<A>(x3, from(rest))));
  88. }
  89. /**
  90. * Construct a list consisting all elements of given array.
  91. * @param array an array; if {@code null} return an empty list
  92. */
  93. public static <A> List<A> from(A[] array) {
  94. List<A> xs = nil();
  95. if (array != null)
  96. for (int i = array.length - 1; i >= 0; i--)
  97. xs = new List<A>(array[i], xs);
  98. return xs;
  99. }
  100. /** Construct a list consisting of a given number of identical elements.
  101. * @param len The number of elements in the list.
  102. * @param init The value of each element.
  103. */
  104. @Deprecated
  105. public static <A> List<A> fill(int len, A init) {
  106. List<A> l = nil();
  107. for (int i = 0; i < len; i++) l = new List<A>(init, l);
  108. return l;
  109. }
  110. /** Does list have no elements?
  111. */
  112. @Override
  113. public boolean isEmpty() {
  114. return tail == null;
  115. }
  116. /** Does list have elements?
  117. */
  118. //@Deprecated
  119. public boolean nonEmpty() {
  120. return tail != null;
  121. }
  122. /** Return the number of elements in this list.
  123. */
  124. //@Deprecated
  125. public int length() {
  126. List<A> l = this;
  127. int len = 0;
  128. while (l.tail != null) {
  129. l = l.tail;
  130. len++;
  131. }
  132. return len;
  133. }
  134. @Override
  135. public int size() {
  136. return length();
  137. }
  138. public List<A> setTail(List<A> tail) {
  139. this.tail = tail;
  140. return tail;
  141. }
  142. /** Prepend given element to front of list, forming and returning
  143. * a new list.
  144. */
  145. public List<A> prepend(A x) {
  146. return new List<A>(x, this);
  147. }
  148. /** Prepend given list of elements to front of list, forming and returning
  149. * a new list.
  150. */
  151. public List<A> prependList(List<A> xs) {
  152. if (this.isEmpty()) return xs;
  153. if (xs.isEmpty()) return this;
  154. if (xs.tail.isEmpty()) return prepend(xs.head);
  155. // return this.prependList(xs.tail).prepend(xs.head);
  156. List<A> result = this;
  157. List<A> rev = xs.reverse();
  158. assert rev != xs;
  159. // since xs.reverse() returned a new list, we can reuse the
  160. // individual List objects, instead of allocating new ones.
  161. while (rev.nonEmpty()) {
  162. List<A> h = rev;
  163. rev = rev.tail;
  164. h.setTail(result);
  165. result = h;
  166. }
  167. return result;
  168. }
  169. /** Reverse list.
  170. * If the list is empty or a singleton, then the same list is returned.
  171. * Otherwise a new list is formed.
  172. */
  173. public List<A> reverse() {
  174. // if it is empty or a singleton, return itself
  175. if (isEmpty() || tail.isEmpty())
  176. return this;
  177. List<A> rev = nil();
  178. for (List<A> l = this; l.nonEmpty(); l = l.tail)
  179. rev = new List<A>(l.head, rev);
  180. return rev;
  181. }
  182. /** Append given element at length, forming and returning
  183. * a new list.
  184. */
  185. public List<A> append(A x) {
  186. return of(x).prependList(this);
  187. }
  188. /** Append given list at length, forming and returning
  189. * a new list.
  190. */
  191. public List<A> appendList(List<A> x) {
  192. return x.prependList(this);
  193. }
  194. /**
  195. * Append given list buffer at length, forming and returning a new
  196. * list.
  197. */
  198. public List<A> appendList(ListBuffer<A> x) {
  199. return appendList(x.toList());
  200. }
  201. /** Copy successive elements of this list into given vector until
  202. * list is exhausted or end of vector is reached.
  203. */
  204. @Override @SuppressWarnings("unchecked")
  205. public <T> T[] toArray(T[] vec) {
  206. int i = 0;
  207. List<A> l = this;
  208. Object[] dest = vec;
  209. while (l.nonEmpty() && i < vec.length) {
  210. dest[i] = l.head;
  211. l = l.tail;
  212. i++;
  213. }
  214. if (l.isEmpty()) {
  215. if (i < vec.length)
  216. vec[i] = null;
  217. return vec;
  218. }
  219. vec = (T[])Array.newInstance(vec.getClass().getComponentType(), size());
  220. return toArray(vec);
  221. }
  222. public Object[] toArray() {
  223. return toArray(new Object[size()]);
  224. }
  225. /** Form a string listing all elements with given separator character.
  226. */
  227. public String toString(String sep) {
  228. if (isEmpty()) {
  229. return "";
  230. } else {
  231. StringBuffer buf = new StringBuffer();
  232. buf.append(head);
  233. for (List<A> l = tail; l.nonEmpty(); l = l.tail) {
  234. buf.append(sep);
  235. buf.append(l.head);
  236. }
  237. return buf.toString();
  238. }
  239. }
  240. /** Form a string listing all elements with comma as the separator character.
  241. */
  242. @Override
  243. public String toString() {
  244. return toString(",");
  245. }
  246. /** Compute a hash code, overrides Object
  247. * @see java.util.List#hashCode
  248. */
  249. @Override
  250. public int hashCode() {
  251. List<A> l = this;
  252. int h = 1;
  253. while (l.tail != null) {
  254. h = h * 31 + (l.head == null ? 0 : l.head.hashCode());
  255. l = l.tail;
  256. }
  257. return h;
  258. }
  259. /** Is this list the same as other list?
  260. * @see java.util.List#equals
  261. */
  262. @Override
  263. public boolean equals(Object other) {
  264. if (other instanceof List<?>)
  265. return equals(this, (List<?>)other);
  266. if (other instanceof java.util.List<?>) {
  267. List<A> t = this;
  268. Iterator<?> oIter = ((java.util.List<?>) other).iterator();
  269. while (t.tail != null && oIter.hasNext()) {
  270. Object o = oIter.next();
  271. if ( !(t.head == null ? o == null : t.head.equals(o)))
  272. return false;
  273. t = t.tail;
  274. }
  275. return (t.isEmpty() && !oIter.hasNext());
  276. }
  277. return false;
  278. }
  279. /** Are the two lists the same?
  280. */
  281. public static boolean equals(List xs, List ys) {
  282. while (xs.tail != null && ys.tail != null) {
  283. if (xs.head == null) {
  284. if (ys.head != null) return false;
  285. } else {
  286. if (!xs.head.equals(ys.head)) return false;
  287. }
  288. xs = xs.tail;
  289. ys = ys.tail;
  290. }
  291. return xs.tail == null && ys.tail == null;
  292. }
  293. /** Does the list contain the specified element?
  294. */
  295. @Override
  296. public boolean contains(Object x) {
  297. List<A> l = this;
  298. while (l.tail != null) {
  299. if (x == null) {
  300. if (l.head == null) return true;
  301. } else {
  302. if (l.head.equals(x)) return true;
  303. }
  304. l = l.tail;
  305. }
  306. return false;
  307. }
  308. /** The last element in the list, if any, or null.
  309. */
  310. public A last() {
  311. A last = null;
  312. List<A> t = this;
  313. while (t.tail != null) {
  314. last = t.head;
  315. t = t.tail;
  316. }
  317. return last;
  318. }
  319. @SuppressWarnings("unchecked")
  320. public static <T> List<T> convert(Class<T> klass, List<?> list) {
  321. if (list == null)
  322. return null;
  323. for (Object o : list)
  324. klass.cast(o);
  325. return (List<T>)list;
  326. }
  327. private static Iterator EMPTYITERATOR = new Iterator() {
  328. public boolean hasNext() {
  329. return false;
  330. }
  331. public Object next() {
  332. throw new java.util.NoSuchElementException();
  333. }
  334. public void remove() {
  335. throw new UnsupportedOperationException();
  336. }
  337. };
  338. @SuppressWarnings("unchecked")
  339. private static <A> Iterator<A> emptyIterator() {
  340. return EMPTYITERATOR;
  341. }
  342. @Override
  343. public Iterator<A> iterator() {
  344. if (tail == null)
  345. return emptyIterator();
  346. return new Iterator<A>() {
  347. List<A> elems = List.this;
  348. public boolean hasNext() {
  349. return elems.tail != null;
  350. }
  351. public A next() {
  352. if (elems.tail == null)
  353. throw new NoSuchElementException();
  354. A result = elems.head;
  355. elems = elems.tail;
  356. return result;
  357. }
  358. public void remove() {
  359. throw new UnsupportedOperationException();
  360. }
  361. };
  362. }
  363. public A get(int index) {
  364. if (index < 0)
  365. throw new IndexOutOfBoundsException(String.valueOf(index));
  366. List<A> l = this;
  367. for (int i = index; i-- > 0 && !l.isEmpty(); l = l.tail)
  368. ;
  369. if (l.isEmpty())
  370. throw new IndexOutOfBoundsException("Index: " + index + ", " +
  371. "Size: " + size());
  372. return l.head;
  373. }
  374. public boolean addAll(int index, Collection<? extends A> c) {
  375. if (c.isEmpty())
  376. return false;
  377. throw new UnsupportedOperationException();
  378. }
  379. public A set(int index, A element) {
  380. throw new UnsupportedOperationException();
  381. }
  382. public void add(int index, A element) {
  383. throw new UnsupportedOperationException();
  384. }
  385. public A remove(int index) {
  386. throw new UnsupportedOperationException();
  387. }
  388. public int indexOf(Object o) {
  389. int i = 0;
  390. for (List<A> l = this; l.tail != null; l = l.tail, i++) {
  391. if (l.head == null ? o == null : l.head.equals(o))
  392. return i;
  393. }
  394. return -1;
  395. }
  396. public int lastIndexOf(Object o) {
  397. int last = -1;
  398. int i = 0;
  399. for (List<A> l = this; l.tail != null; l = l.tail, i++) {
  400. if (l.head == null ? o == null : l.head.equals(o))
  401. last = i;
  402. }
  403. return last;
  404. }
  405. public ListIterator<A> listIterator() {
  406. return Collections.unmodifiableList(new ArrayList<A>(this)).listIterator();
  407. }
  408. public ListIterator<A> listIterator(int index) {
  409. return Collections.unmodifiableList(new ArrayList<A>(this)).listIterator(index);
  410. }
  411. public java.util.List<A> subList(int fromIndex, int toIndex) {
  412. if (fromIndex < 0 || toIndex > size() || fromIndex > toIndex)
  413. throw new IllegalArgumentException();
  414. ArrayList<A> a = new ArrayList<A>(toIndex - fromIndex);
  415. int i = 0;
  416. for (List<A> l = this; l.tail != null; l = l.tail, i++) {
  417. if (i == toIndex)
  418. break;
  419. if (i >= fromIndex)
  420. a.add(l.head);
  421. }
  422. return Collections.unmodifiableList(a);
  423. }
  424. }