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 1998-2006 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 com.sun.javadoc.*;
30 /**
31 * Documents a Serializable field defined by an ObjectStreamField.
32 * <pre>
33 * The class parses and stores the three serialField tag parameters:
34 *
35 * - field name
36 * - field type name
37 * (fully-qualified or visible from the current import context)
38 * - description of the valid values for the field
40 * </pre>
41 * This tag is only allowed in the javadoc for the special member
42 * serialPersistentFields.
43 *
44 * @author Joe Fialli
45 * @author Neal Gafter
46 *
47 * @see java.io.ObjectStreamField
48 */
49 class SerialFieldTagImpl
50 extends TagImpl
51 implements SerialFieldTag, Comparable<Object>
52 {
53 //### These could be final, except that the constructor
54 //### does not set them directly.
56 private String fieldName; // Required Argument 1 of serialField
57 private String fieldType; // Required Argument 2 of serialField
58 private String description; // Optional Remaining Arguments of serialField
60 private ClassDoc containingClass; // Class containing serialPersistentField member
61 private ClassDoc fieldTypeDoc; // ClassDocImpl of fieldType
62 private FieldDocImpl matchingField; // FieldDocImpl with same name as fieldName
64 /* Constructor. */
65 SerialFieldTagImpl(DocImpl holder, String name, String text) {
66 super(holder, name, text);
67 parseSerialFieldString();
68 if (holder instanceof MemberDoc) {
69 containingClass = ((MemberDocImpl)holder).containingClass();
70 }
71 }
73 /*
74 * The serialField tag is composed of three entities.
75 *
76 * serialField serializableFieldName serisliableFieldType
77 * description of field.
78 *
79 * The fieldName and fieldType must be legal Java Identifiers.
80 */
81 private void parseSerialFieldString() {
82 int len = text.length();
84 // if no white space found
85 /* Skip white space. */
86 int inx = 0;
87 int cp;
88 for (; inx < len; inx += Character.charCount(cp)) {
89 cp = text.codePointAt(inx);
90 if (!Character.isWhitespace(cp)) {
91 break;
92 }
93 }
95 /* find first word. */
96 int first = inx;
97 int last = inx;
98 cp = text.codePointAt(inx);
99 if (! Character.isJavaIdentifierStart(cp)) {
100 docenv().warning(holder,
101 "tag.serialField.illegal_character",
102 new String(Character.toChars(cp)), text);
103 return;
104 }
106 for (inx += Character.charCount(cp); inx < len; inx += Character.charCount(cp)) {
107 cp = text.codePointAt(inx);
108 if (!Character.isJavaIdentifierPart(cp)) {
109 break;
110 }
111 }
113 if (inx < len && ! Character.isWhitespace(cp = text.codePointAt(inx))) {
114 docenv().warning(holder,
115 "tag.serialField.illegal_character",
116 new String(Character.toChars(cp)), text);
117 return;
118 }
120 last = inx;
121 fieldName = text.substring(first, last);
123 /* Skip white space. */
124 for (; inx < len; inx += Character.charCount(cp)) {
125 cp = text.codePointAt(inx);
126 if (!Character.isWhitespace(cp)) {
127 break;
128 }
129 }
131 /* find second word. */
132 first = inx;
133 last = inx;
135 for (; inx < len; inx += Character.charCount(cp)) {
136 cp = text.codePointAt(inx);
137 if (Character.isWhitespace(cp)) {
138 break;
139 }
140 }
141 if (inx < len && ! Character.isWhitespace(cp = text.codePointAt(inx))) {
142 docenv().warning(holder,
143 "tag.serialField.illegal_character",
144 new String(Character.toChars(cp)), text);
145 return;
146 }
147 last = inx;
148 fieldType = text.substring(first, last);
150 /* Skip leading white space. Rest of string is description for serialField.*/
151 for (; inx < len; inx += Character.charCount(cp)) {
152 cp = text.codePointAt(inx);
153 if (!Character.isWhitespace(cp)) {
154 break;
155 }
156 }
157 description = text.substring(inx);
158 }
160 /**
161 * return a key for sorting.
162 */
163 String key() {
164 return fieldName;
165 }
167 /*
168 * Optional. Link this serialField tag to its corrsponding
169 * field in the class. Note: there is no requirement that
170 * there be a field in the class that matches serialField tag.
171 */
172 void mapToFieldDocImpl(FieldDocImpl fd) {
173 matchingField = fd;
174 }
176 /**
177 * Return the serialziable field name.
178 */
179 public String fieldName() {
180 return fieldName;
181 }
183 /**
184 * Return the field type string.
185 */
186 public String fieldType() {
187 return fieldType;
188 }
190 /**
191 * Return the ClassDocImpl for field type.
192 *
193 * @returns null if no ClassDocImpl for field type is visible from
194 * containingClass context.
195 */
196 public ClassDoc fieldTypeDoc() {
197 if (fieldTypeDoc == null && containingClass != null) {
198 fieldTypeDoc = containingClass.findClass(fieldType);
199 }
200 return fieldTypeDoc;
201 }
203 /**
204 * Return the corresponding FieldDocImpl for this SerialFieldTagImpl.
205 *
206 * @returns null if no matching FieldDocImpl.
207 */
208 FieldDocImpl getMatchingField() {
209 return matchingField;
210 }
212 /**
213 * Return the field comment. If there is no serialField comment, return
214 * javadoc comment of corresponding FieldDocImpl.
215 */
216 public String description() {
217 if (description.length() == 0 && matchingField != null) {
219 //check for javadoc comment of corresponding field.
220 Comment comment = matchingField.comment();
221 if (comment != null) {
222 return comment.commentText();
223 }
224 }
225 return description;
226 }
228 /**
229 * Return the kind of this tag.
230 */
231 public String kind() {
232 return "@serialField";
233 }
235 /**
236 * Convert this object to a string.
237 */
238 public String toString() {
239 return name + ":" + text;
240 }
242 /**
243 * Compares this Object with the specified Object for order. Returns a
244 * negative integer, zero, or a positive integer as this Object is less
245 * than, equal to, or greater than the given Object.
246 * <p>
247 * Included to make SerialFieldTagImpl items java.lang.Comparable.
248 *
249 * @param obj the <code>Object</code> to be compared.
250 * @return a negative integer, zero, or a positive integer as this Object
251 * is less than, equal to, or greater than the given Object.
252 * @exception ClassCastException the specified Object's type prevents it
253 * from being compared to this Object.
254 * @since 1.2
255 */
256 public int compareTo(Object obj) {
257 return key().compareTo(((SerialFieldTagImpl)obj).key());
258 }
259 }