Fri, 30 Nov 2012 15:14:48 +0000
8002099: Add support for intersection types in cast expression
Summary: Add parser and type-checking support for intersection types in cast expressions
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1997, 2012, 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 */
26 package com.sun.tools.javadoc;
28 import java.io.IOException;
29 import java.io.InputStream;
31 import javax.tools.FileObject;
33 import com.sun.javadoc.*;
34 import com.sun.tools.javac.code.Attribute;
35 import com.sun.tools.javac.code.Scope;
36 import com.sun.tools.javac.code.Symbol.ClassSymbol;
37 import com.sun.tools.javac.code.Symbol.PackageSymbol;
38 import com.sun.tools.javac.tree.JCTree;
39 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
40 import com.sun.tools.javac.util.List;
41 import com.sun.tools.javac.util.ListBuffer;
42 import com.sun.tools.javac.util.Name;
43 import com.sun.tools.javac.util.Position;
45 /**
46 * Represents a java package. Provides access to information
47 * about the package, the package's comment and tags, and the
48 * classes in the package.
49 *
50 * <p><b>This is NOT part of any supported API.
51 * If you write code that depends on this, you do so at your own risk.
52 * This code and its internal interfaces are subject to change or
53 * deletion without notice.</b>
54 *
55 * @since 1.2
56 * @author Kaiyang Liu (original)
57 * @author Robert Field (rewrite)
58 * @author Neal Gafter (rewrite)
59 * @author Scott Seligman (package-info.java)
60 */
62 public class PackageDocImpl extends DocImpl implements PackageDoc {
64 protected PackageSymbol sym;
65 private JCCompilationUnit tree = null; // for source position
67 public FileObject docPath = null;
68 private boolean foundDoc; // found a doc comment in either
69 // package.html or package-info.java
71 boolean isIncluded = false; // Set in RootDocImpl.
72 public boolean setDocPath = false; //Flag to avoid setting doc path multiple times.
74 /**
75 * Constructor
76 */
77 public PackageDocImpl(DocEnv env, PackageSymbol sym) {
78 this(env, sym, null, null);
79 }
81 /**
82 * Constructor
83 */
84 public PackageDocImpl(DocEnv env, PackageSymbol sym,
85 String documentation, JCTree tree) {
86 super(env, documentation);
87 this.sym = sym;
88 this.tree = (JCCompilationUnit) tree;
89 foundDoc = (documentation != null);
90 }
92 void setTree(JCTree tree) {
93 this.tree = (JCCompilationUnit) tree;
94 }
96 public void setRawCommentText(String rawDocumentation) {
97 super.setRawCommentText(rawDocumentation);
98 checkDoc();
99 }
101 /**
102 * Do lazy initialization of "documentation" string.
103 */
104 protected String documentation() {
105 if (documentation != null)
106 return documentation;
107 if (docPath != null) {
108 // read from file
109 try {
110 InputStream s = docPath.openInputStream();
111 documentation = readHTMLDocumentation(s, docPath);
112 } catch (IOException exc) {
113 documentation = "";
114 env.error(null, "javadoc.File_Read_Error", docPath.getName());
115 }
116 } else {
117 // no doc file to be had
118 documentation = "";
119 }
120 return documentation;
121 }
123 /**
124 * Cache of all classes contained in this package, including
125 * member classes of those classes, and their member classes, etc.
126 * Includes only those classes at the specified protection level
127 * and weaker.
128 */
129 private List<ClassDocImpl> allClassesFiltered = null;
131 /**
132 * Cache of all classes contained in this package, including
133 * member classes of those classes, and their member classes, etc.
134 */
135 private List<ClassDocImpl> allClasses = null;
137 /**
138 * Return a list of all classes contained in this package, including
139 * member classes of those classes, and their member classes, etc.
140 */
141 private List<ClassDocImpl> getClasses(boolean filtered) {
142 if (allClasses != null && !filtered) {
143 return allClasses;
144 }
145 if (allClassesFiltered != null && filtered) {
146 return allClassesFiltered;
147 }
148 ListBuffer<ClassDocImpl> classes = new ListBuffer<ClassDocImpl>();
149 for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) {
150 if (e.sym != null) {
151 ClassSymbol s = (ClassSymbol)e.sym;
152 ClassDocImpl c = env.getClassDoc(s);
153 if (c != null && !c.isSynthetic())
154 c.addAllClasses(classes, filtered);
155 }
156 }
157 if (filtered)
158 return allClassesFiltered = classes.toList();
159 else
160 return allClasses = classes.toList();
161 }
163 /**
164 * Add all included classes (including Exceptions and Errors)
165 * and interfaces.
166 */
167 public void addAllClassesTo(ListBuffer<ClassDocImpl> list) {
168 list.appendList(getClasses(true));
169 }
171 /**
172 * Get all classes (including Exceptions and Errors)
173 * and interfaces.
174 * @since J2SE1.4.
175 *
176 * @return all classes and interfaces in this package, filtered to include
177 * only the included classes if filter==true.
178 */
179 public ClassDoc[] allClasses(boolean filter) {
180 List<ClassDocImpl> classes = getClasses(filter);
181 return classes.toArray(new ClassDocImpl[classes.length()]);
182 }
184 /**
185 * Get all included classes (including Exceptions and Errors)
186 * and interfaces. Same as allClasses(true).
187 *
188 * @return all included classes and interfaces in this package.
189 */
190 public ClassDoc[] allClasses() {
191 return allClasses(true);
192 }
194 /**
195 * Get ordinary classes (that is, exclude exceptions, errors,
196 * enums, interfaces, and annotation types) in this package.
197 *
198 * @return included ordinary classes in this package.
199 */
200 public ClassDoc[] ordinaryClasses() {
201 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
202 for (ClassDocImpl c : getClasses(true)) {
203 if (c.isOrdinaryClass()) {
204 ret.append(c);
205 }
206 }
207 return ret.toArray(new ClassDocImpl[ret.length()]);
208 }
210 /**
211 * Get Exception classes in this package.
212 *
213 * @return included Exceptions in this package.
214 */
215 public ClassDoc[] exceptions() {
216 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
217 for (ClassDocImpl c : getClasses(true)) {
218 if (c.isException()) {
219 ret.append(c);
220 }
221 }
222 return ret.toArray(new ClassDocImpl[ret.length()]);
223 }
225 /**
226 * Get Error classes in this package.
227 *
228 * @return included Errors in this package.
229 */
230 public ClassDoc[] errors() {
231 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
232 for (ClassDocImpl c : getClasses(true)) {
233 if (c.isError()) {
234 ret.append(c);
235 }
236 }
237 return ret.toArray(new ClassDocImpl[ret.length()]);
238 }
240 /**
241 * Get included enum types in this package.
242 *
243 * @return included enum types in this package.
244 */
245 public ClassDoc[] enums() {
246 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
247 for (ClassDocImpl c : getClasses(true)) {
248 if (c.isEnum()) {
249 ret.append(c);
250 }
251 }
252 return ret.toArray(new ClassDocImpl[ret.length()]);
253 }
255 /**
256 * Get included interfaces in this package, omitting annotation types.
257 *
258 * @return included interfaces in this package.
259 */
260 public ClassDoc[] interfaces() {
261 ListBuffer<ClassDocImpl> ret = new ListBuffer<ClassDocImpl>();
262 for (ClassDocImpl c : getClasses(true)) {
263 if (c.isInterface()) {
264 ret.append(c);
265 }
266 }
267 return ret.toArray(new ClassDocImpl[ret.length()]);
268 }
270 /**
271 * Get included annotation types in this package.
272 *
273 * @return included annotation types in this package.
274 */
275 public AnnotationTypeDoc[] annotationTypes() {
276 ListBuffer<AnnotationTypeDocImpl> ret =
277 new ListBuffer<AnnotationTypeDocImpl>();
278 for (ClassDocImpl c : getClasses(true)) {
279 if (c.isAnnotationType()) {
280 ret.append((AnnotationTypeDocImpl)c);
281 }
282 }
283 return ret.toArray(new AnnotationTypeDocImpl[ret.length()]);
284 }
286 /**
287 * Get the annotations of this package.
288 * Return an empty array if there are none.
289 */
290 public AnnotationDesc[] annotations() {
291 AnnotationDesc res[] = new AnnotationDesc[sym.getAnnotationMirrors().length()];
292 int i = 0;
293 for (Attribute.Compound a : sym.getAnnotationMirrors()) {
294 res[i++] = new AnnotationDescImpl(env, a);
295 }
296 return res;
297 }
300 /**
301 * Lookup for a class within this package.
302 *
303 * @return ClassDocImpl of found class, or null if not found.
304 */
305 public ClassDoc findClass(String className) {
306 final boolean filtered = true;
307 for (ClassDocImpl c : getClasses(filtered)) {
308 if (c.name().equals(className)) {
309 return c;
310 }
311 }
312 return null;
313 }
315 /**
316 * Return true if this package is included in the active set.
317 */
318 public boolean isIncluded() {
319 return isIncluded;
320 }
322 /**
323 * Get package name.
324 *
325 * Note that we do not provide a means of obtaining the simple
326 * name of a package -- package names are always returned in their
327 * uniquely qualified form.
328 */
329 public String name() {
330 return qualifiedName();
331 }
333 /**
334 * Get package name.
335 */
336 public String qualifiedName() {
337 Name fullname = sym.getQualifiedName();
338 // Some bogus tests depend on the interned "" being returned.
339 // See 6457276.
340 return fullname.isEmpty() ? "" : fullname.toString();
341 }
343 /**
344 * set doc path for an unzipped directory
345 */
346 public void setDocPath(FileObject path) {
347 setDocPath = true;
348 if (path == null)
349 return;
350 if (!path.equals(docPath)) {
351 docPath = path;
352 checkDoc();
353 }
354 }
356 // Has checkDoc() sounded off yet?
357 private boolean checkDocWarningEmitted = false;
359 /**
360 * Invoked when a source of package doc comments is located.
361 * Emits a diagnostic if this is the second one.
362 */
363 private void checkDoc() {
364 if (foundDoc) {
365 if (!checkDocWarningEmitted) {
366 env.warning(null, "javadoc.Multiple_package_comments", name());
367 checkDocWarningEmitted = true;
368 }
369 } else {
370 foundDoc = true;
371 }
372 }
374 /**
375 * Return the source position of the entity, or null if
376 * no position is available.
377 */
378 public SourcePosition position() {
379 return (tree != null)
380 ? SourcePositionImpl.make(tree.sourcefile, tree.pos, tree.lineMap)
381 : SourcePositionImpl.make(docPath, Position.NOPOS, null);
382 }
383 }