1 /* 2 * Copyright (c) 2001, 2008, 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 26 package com.sun.tools.javac.comp; 27 28 import java.util.AbstractQueue; 29 import com.sun.tools.javac.util.Context; 30 import java.util.HashMap; 31 import java.util.Iterator; 32 import java.util.LinkedList; 33 import java.util.Map; 34 import java.util.Queue; 35 import javax.tools.JavaFileObject; 36 37 /** A queue of all as yet unattributed classes. 38 * 39 * <p><b>This is NOT part of any supported API. 40 * If you write code that depends on this, you do so at your own risk. 41 * This code and its internal interfaces are subject to change or 42 * deletion without notice.</b> 43 */ 44 public class Todo extends AbstractQueue<Env<AttrContext>> { 45 /** The context key for the todo list. */ 46 protected static final Context.Key<Todo> todoKey = 47 new Context.Key<Todo>(); 48 49 /** Get the Todo instance for this context. */ instance(Context context)50 public static Todo instance(Context context) { 51 Todo instance = context.get(todoKey); 52 if (instance == null) 53 instance = new Todo(context); 54 return instance; 55 } 56 57 /** Create a new todo list. */ Todo(Context context)58 protected Todo(Context context) { 59 context.put(todoKey, this); 60 } 61 append(Env<AttrContext> env)62 public void append(Env<AttrContext> env) { 63 add(env); 64 } 65 66 @Override iterator()67 public Iterator<Env<AttrContext>> iterator() { 68 return contents.iterator(); 69 } 70 71 @Override size()72 public int size() { 73 return contents.size(); 74 } 75 offer(Env<AttrContext> e)76 public boolean offer(Env<AttrContext> e) { 77 if (contents.add(e)) { 78 if (contentsByFile != null) 79 addByFile(e); 80 return true; 81 } else { 82 return false; 83 } 84 } 85 poll()86 public Env<AttrContext> poll() { 87 if (size() == 0) 88 return null; 89 Env<AttrContext> env = contents.remove(0); 90 if (contentsByFile != null) 91 removeByFile(env); 92 return env; 93 } 94 peek()95 public Env<AttrContext> peek() { 96 return (size() == 0 ? null : contents.get(0)); 97 } 98 groupByFile()99 public Queue<Queue<Env<AttrContext>>> groupByFile() { 100 if (contentsByFile == null) { 101 contentsByFile = new LinkedList<Queue<Env<AttrContext>>>(); 102 for (Env<AttrContext> env: contents) { 103 addByFile(env); 104 } 105 } 106 return contentsByFile; 107 } 108 addByFile(Env<AttrContext> env)109 private void addByFile(Env<AttrContext> env) { 110 JavaFileObject file = env.toplevel.sourcefile; 111 if (fileMap == null) 112 fileMap = new HashMap<JavaFileObject, FileQueue>(); 113 FileQueue fq = fileMap.get(file); 114 if (fq == null) { 115 fq = new FileQueue(); 116 fileMap.put(file, fq); 117 contentsByFile.add(fq); 118 } 119 fq.fileContents.add(env); 120 } 121 removeByFile(Env<AttrContext> env)122 private void removeByFile(Env<AttrContext> env) { 123 JavaFileObject file = env.toplevel.sourcefile; 124 FileQueue fq = fileMap.get(file); 125 if (fq == null) 126 return; 127 if (fq.fileContents.remove(env)) { 128 if (fq.isEmpty()) { 129 fileMap.remove(file); 130 contentsByFile.remove(fq); 131 } 132 } 133 } 134 135 LinkedList<Env<AttrContext>> contents = new LinkedList<Env<AttrContext>>(); 136 LinkedList<Queue<Env<AttrContext>>> contentsByFile; 137 Map<JavaFileObject, FileQueue> fileMap; 138 139 class FileQueue extends AbstractQueue<Env<AttrContext>> { 140 @Override iterator()141 public Iterator<Env<AttrContext>> iterator() { 142 return fileContents.iterator(); 143 } 144 145 @Override size()146 public int size() { 147 return fileContents.size(); 148 } 149 offer(Env<AttrContext> e)150 public boolean offer(Env<AttrContext> e) { 151 if (fileContents.offer(e)) { 152 contents.add(e); 153 return true; 154 } 155 return false; 156 } 157 poll()158 public Env<AttrContext> poll() { 159 if (fileContents.size() == 0) 160 return null; 161 Env<AttrContext> env = fileContents.remove(0); 162 contents.remove(env); 163 return env; 164 } 165 peek()166 public Env<AttrContext> peek() { 167 return (fileContents.size() == 0 ? null : fileContents.get(0)); 168 } 169 170 LinkedList<Env<AttrContext>> fileContents = new LinkedList<Env<AttrContext>>(); 171 } 172 } 173