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