Tue, 11 Aug 2009 01:13:14 +0100
6521805: Regression: JDK5/JDK6 javac allows write access to outer class reference
Summary: javac should warn/complain about identifiers with the same name as synthetic symbol
Reviewed-by: jjg
1 /*
2 * Copyright 1997-2009 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
26 package com.sun.tools.javadoc;
28 import java.io.InputStream;
29 import java.io.IOException;
30 import java.text.CollationKey;
31 import javax.tools.FileObject;
33 import com.sun.javadoc.*;
35 import com.sun.tools.javac.util.Position;
37 /**
38 * abstract base class of all Doc classes. Doc item's are representations
39 * of java language constructs (class, package, method,...) which have
40 * comments and have been processed by this run of javadoc. All Doc items
41 * are unique, that is, they are == comparable.
42 *
43 * @since 1.2
44 * @author Robert Field
45 * @author Atul M Dambalkar
46 * @author Neal Gafter (rewrite)
47 */
48 public abstract class DocImpl implements Doc, Comparable<Object> {
50 /**
51 * Doc environment
52 */
53 protected final DocEnv env; //### Rename this everywhere to 'docenv' ?
55 /**
56 * The complex comment object, lazily initialized.
57 */
58 private Comment comment;
60 /**
61 * The cached sort key, to take care of Natural Language Text sorting.
62 */
63 private CollationKey collationkey = null;
65 /**
66 * Raw documentation string.
67 */
68 protected String documentation; // Accessed in PackageDocImpl, RootDocImpl
70 /**
71 * Cached first sentence.
72 */
73 private Tag[] firstSentence;
75 /**
76 * Cached inline tags.
77 */
78 private Tag[] inlineTags;
80 /**
81 * Constructor.
82 */
83 DocImpl(DocEnv env, String documentation) {
84 this.documentation = documentation;
85 this.env = env;
86 }
88 /**
89 * So subclasses have the option to do lazy initialization of
90 * "documentation" string.
91 */
92 String documentation() {
93 if (documentation == null) documentation = "";
94 return documentation;
95 }
97 /**
98 * For lazy initialization of comment.
99 */
100 Comment comment() {
101 if (comment == null) {
102 comment = new Comment(this, documentation());
103 }
104 return comment;
105 }
107 /**
108 * Return the text of the comment for this doc item.
109 * TagImpls have been removed.
110 */
111 public String commentText() {
112 return comment().commentText();
113 }
115 /**
116 * Return all tags in this Doc item.
117 *
118 * @return an array of TagImpl containing all tags on this Doc item.
119 */
120 public Tag[] tags() {
121 return comment().tags();
122 }
124 /**
125 * Return tags of the specified kind in this Doc item.
126 *
127 * @param tagname name of the tag kind to search for.
128 * @return an array of TagImpl containing all tags whose 'kind()'
129 * matches 'tagname'.
130 */
131 public Tag[] tags(String tagname) {
132 return comment().tags(tagname);
133 }
135 /**
136 * Return the see also tags in this Doc item.
137 *
138 * @return an array of SeeTag containing all @see tags.
139 */
140 public SeeTag[] seeTags() {
141 return comment().seeTags();
142 }
144 public Tag[] inlineTags() {
145 if (inlineTags == null) {
146 inlineTags = Comment.getInlineTags(this, commentText());
147 }
148 return inlineTags;
149 }
151 public Tag[] firstSentenceTags() {
152 if (firstSentence == null) {
153 //Parse all sentences first to avoid duplicate warnings.
154 inlineTags();
155 try {
156 env.setSilent(true);
157 firstSentence = Comment.firstSentenceTags(this, commentText());
158 } finally {
159 env.setSilent(false);
160 }
161 }
162 return firstSentence;
163 }
165 /**
166 * Utility for subclasses which read HTML documentation files.
167 */
168 String readHTMLDocumentation(InputStream input, FileObject filename) throws IOException {
169 int filesize = input.available();
170 byte[] filecontents = new byte[filesize];
171 input.read(filecontents, 0, filesize);
172 input.close();
173 String encoding = env.getEncoding();
174 String rawDoc = (encoding!=null)
175 ? new String(filecontents, encoding)
176 : new String(filecontents);
177 String upper = null;
178 int bodyIdx = rawDoc.indexOf("<body");
179 if (bodyIdx == -1) {
180 bodyIdx = rawDoc.indexOf("<BODY");
181 if (bodyIdx == -1) {
182 upper = rawDoc.toUpperCase();
183 bodyIdx = upper.indexOf("<BODY");
184 if (bodyIdx == -1) {
185 env.error(SourcePositionImpl.make(filename, Position.NOPOS, null),
186 "javadoc.Body_missing_from_html_file");
187 return "";
188 }
189 }
190 }
191 bodyIdx = rawDoc.indexOf('>', bodyIdx);
192 if (bodyIdx == -1) {
193 env.error(SourcePositionImpl.make(filename, Position.NOPOS, null),
194 "javadoc.Body_missing_from_html_file");
195 return "";
196 }
197 ++bodyIdx;
198 int endIdx = rawDoc.indexOf("</body", bodyIdx);
199 if (endIdx == -1) {
200 endIdx = rawDoc.indexOf("</BODY", bodyIdx);
201 if (endIdx == -1) {
202 if (upper == null) {
203 upper = rawDoc.toUpperCase();
204 }
205 endIdx = upper.indexOf("</BODY", bodyIdx);
206 if (endIdx == -1) {
207 env.error(SourcePositionImpl.make(filename, Position.NOPOS, null),
208 "javadoc.End_body_missing_from_html_file");
209 return "";
210 }
211 }
212 }
213 return rawDoc.substring(bodyIdx, endIdx);
214 }
216 /**
217 * Return the full unprocessed text of the comment. Tags
218 * are included as text. Used mainly for store and retrieve
219 * operations like internalization.
220 */
221 public String getRawCommentText() {
222 return documentation();
223 }
225 /**
226 * Set the full unprocessed text of the comment. Tags
227 * are included as text. Used mainly for store and retrieve
228 * operations like internalization.
229 */
230 public void setRawCommentText(String rawDocumentation) {
231 documentation = rawDocumentation;
232 comment = null;
233 }
235 /**
236 * return a key for sorting.
237 */
238 CollationKey key() {
239 if (collationkey == null) {
240 collationkey = generateKey();
241 }
242 return collationkey;
243 }
245 /**
246 * Generate a key for sorting.
247 * <p>
248 * Default is name().
249 */
250 CollationKey generateKey() {
251 String k = name();
252 // System.out.println("COLLATION KEY FOR " + this + " is \"" + k + "\"");
253 return env.doclocale.collator.getCollationKey(k);
254 }
256 /**
257 * Returns a string representation of this Doc item.
258 */
259 public String toString() {
260 return qualifiedName();
261 }
263 /**
264 * Returns the name of this Doc item.
265 *
266 * @return the name
267 */
268 public abstract String name();
270 /**
271 * Returns the qualified name of this Doc item.
272 *
273 * @return the name
274 */
275 public abstract String qualifiedName();
277 /**
278 * Compares this Object with the specified Object for order. Returns a
279 * negative integer, zero, or a positive integer as this Object is less
280 * than, equal to, or greater than the given Object.
281 * <p>
282 * Included so that Doc item are java.lang.Comparable.
283 *
284 * @param o the <code>Object</code> to be compared.
285 * @return a negative integer, zero, or a positive integer as this Object
286 * is less than, equal to, or greater than the given Object.
287 * @exception ClassCastException the specified Object's type prevents it
288 * from being compared to this Object.
289 */
290 public int compareTo(Object obj) {
291 // System.out.println("COMPARE \"" + this + "\" to \"" + obj + "\" = " + key().compareTo(((DocImpl)obj).key()));
292 return key().compareTo(((DocImpl)obj).key());
293 }
295 /**
296 * Is this Doc item a field? False until overridden.
297 *
298 * @return true if it represents a field
299 */
300 public boolean isField() {
301 return false;
302 }
304 /**
305 * Is this Doc item an enum constant? False until overridden.
306 *
307 * @return true if it represents an enum constant
308 */
309 public boolean isEnumConstant() {
310 return false;
311 }
313 /**
314 * Is this Doc item a constructor? False until overridden.
315 *
316 * @return true if it represents a constructor
317 */
318 public boolean isConstructor() {
319 return false;
320 }
322 /**
323 * Is this Doc item a method (but not a constructor or annotation
324 * type element)?
325 * False until overridden.
326 *
327 * @return true if it represents a method
328 */
329 public boolean isMethod() {
330 return false;
331 }
333 /**
334 * Is this Doc item an annotation type element?
335 * False until overridden.
336 *
337 * @return true if it represents an annotation type element
338 */
339 public boolean isAnnotationTypeElement() {
340 return false;
341 }
343 /**
344 * Is this Doc item a interface (but not an annotation type)?
345 * False until overridden.
346 *
347 * @return true if it represents a interface
348 */
349 public boolean isInterface() {
350 return false;
351 }
353 /**
354 * Is this Doc item a exception class? False until overridden.
355 *
356 * @return true if it represents a exception
357 */
358 public boolean isException() {
359 return false;
360 }
362 /**
363 * Is this Doc item a error class? False until overridden.
364 *
365 * @return true if it represents a error
366 */
367 public boolean isError() {
368 return false;
369 }
371 /**
372 * Is this Doc item an enum type? False until overridden.
373 *
374 * @return true if it represents an enum type
375 */
376 public boolean isEnum() {
377 return false;
378 }
380 /**
381 * Is this Doc item an annotation type? False until overridden.
382 *
383 * @return true if it represents an annotation type
384 */
385 public boolean isAnnotationType() {
386 return false;
387 }
389 /**
390 * Is this Doc item an ordinary class (i.e. not an interface,
391 * annotation type, enumeration, exception, or error)?
392 * False until overridden.
393 *
394 * @return true if it represents an ordinary class
395 */
396 public boolean isOrdinaryClass() {
397 return false;
398 }
400 /**
401 * Is this Doc item a class
402 * (and not an interface or annotation type)?
403 * This includes ordinary classes, enums, errors and exceptions.
404 * False until overridden.
405 *
406 * @return true if it represents a class
407 */
408 public boolean isClass() {
409 return false;
410 }
412 /**
413 * return true if this Doc is include in the active set.
414 */
415 public abstract boolean isIncluded();
417 /**
418 * Return the source position of the entity, or null if
419 * no position is available.
420 */
421 public SourcePosition position() { return null; }
422 }