author | jjg |
Mon, 09 May 2016 16:52:15 -0700 | |
changeset 37938 | 42baa89d2156 |
parent 27224 | langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SeeTagImpl.java@228abfa87080 |
child 38617 | d93a7f64e231 |
permissions | -rw-r--r-- |
10 | 1 |
/* |
23794
9437acfa99e9
8031625: javadoc problems referencing inner class constructors
bpatel
parents:
22163
diff
changeset
|
2 |
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. |
10 | 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 |
|
5520 | 7 |
* published by the Free Software Foundation. Oracle designates this |
10 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5520 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
10 | 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 |
* |
|
5520 | 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. |
|
10 | 24 |
*/ |
25 |
||
37938
42baa89d2156
8075703: jdk.javadoc module exports com.sun.tools.javadoc package which contains a lot of internal API.
jjg
parents:
27224
diff
changeset
|
26 |
package com.sun.tools.javadoc.main; |
10 | 27 |
|
14541
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
28 |
import java.io.File; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
29 |
import java.util.Locale; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
30 |
|
14258 | 31 |
import com.sun.javadoc.*; |
14541
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
32 |
import com.sun.tools.javac.code.Printer; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
33 |
import com.sun.tools.javac.code.Symbol; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
34 |
import com.sun.tools.javac.code.Type.CapturedType; |
10 | 35 |
import com.sun.tools.javac.util.*; |
36 |
||
27224
228abfa87080
8054457: Refactor Symbol kinds from small ints to an enum
emc
parents:
25874
diff
changeset
|
37 |
import static com.sun.tools.javac.code.Kinds.Kind.*; |
228abfa87080
8054457: Refactor Symbol kinds from small ints to an enum
emc
parents:
25874
diff
changeset
|
38 |
|
10 | 39 |
/** |
40 |
* Represents a see also documentation tag. |
|
41 |
* The @see tag can be plain text, or reference a class or member. |
|
42 |
* |
|
14260
727a84636f12
8000665: fix "internal API" comments on javadoc files
jjg
parents:
14258
diff
changeset
|
43 |
* <p><b>This is NOT part of any supported API. |
727a84636f12
8000665: fix "internal API" comments on javadoc files
jjg
parents:
14258
diff
changeset
|
44 |
* If you write code that depends on this, you do so at your own risk. |
727a84636f12
8000665: fix "internal API" comments on javadoc files
jjg
parents:
14258
diff
changeset
|
45 |
* This code and its internal interfaces are subject to change or |
727a84636f12
8000665: fix "internal API" comments on javadoc files
jjg
parents:
14258
diff
changeset
|
46 |
* deletion without notice.</b> |
727a84636f12
8000665: fix "internal API" comments on javadoc files
jjg
parents:
14258
diff
changeset
|
47 |
* |
10 | 48 |
* @author Kaiyang Liu (original) |
49 |
* @author Robert Field (rewrite) |
|
50 |
* @author Atul M Dambalkar |
|
51 |
* |
|
52 |
*/ |
|
53 |
class SeeTagImpl extends TagImpl implements SeeTag, LayoutCharacters { |
|
54 |
||
55 |
//### TODO: Searching for classes, fields, and methods |
|
56 |
//### should follow the normal rules applied by the compiler. |
|
57 |
||
58 |
/** |
|
59 |
* where of where#what - i.e. the class name (may be empty) |
|
60 |
*/ |
|
61 |
private String where; |
|
62 |
||
63 |
/** |
|
64 |
* what of where#what - i.e. the member (may be null) |
|
65 |
*/ |
|
66 |
private String what; |
|
67 |
||
68 |
private PackageDoc referencedPackage; |
|
69 |
private ClassDoc referencedClass; |
|
70 |
private MemberDoc referencedMember; |
|
71 |
||
72 |
String label = ""; |
|
73 |
||
74 |
SeeTagImpl(DocImpl holder, String name, String text) { |
|
75 |
super(holder, name, text); |
|
76 |
parseSeeString(); |
|
77 |
if (where != null) { |
|
78 |
ClassDocImpl container = null; |
|
79 |
if (holder instanceof MemberDoc) { |
|
80 |
container = |
|
81 |
(ClassDocImpl)((ProgramElementDoc)holder).containingClass(); |
|
82 |
} else if (holder instanceof ClassDoc) { |
|
83 |
container = (ClassDocImpl)holder; |
|
84 |
} |
|
85 |
findReferenced(container); |
|
14541
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
86 |
if (showRef) showRef(); |
10 | 87 |
} |
88 |
} |
|
89 |
||
14541
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
90 |
private static final boolean showRef = false; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
91 |
|
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
92 |
private void showRef() { |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
93 |
Symbol sym; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
94 |
if (referencedMember != null) { |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
95 |
if (referencedMember instanceof MethodDocImpl) |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
96 |
sym = ((MethodDocImpl) referencedMember).sym; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
97 |
else if (referencedMember instanceof FieldDocImpl) |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
98 |
sym = ((FieldDocImpl) referencedMember).sym; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
99 |
else |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
100 |
sym = ((ConstructorDocImpl) referencedMember).sym; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
101 |
} else if (referencedClass != null) { |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
102 |
sym = ((ClassDocImpl) referencedClass).tsym; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
103 |
} else if (referencedPackage != null) { |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
104 |
sym = ((PackageDocImpl) referencedPackage).sym; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
105 |
} else |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
106 |
return; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
107 |
|
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
108 |
final JavacMessages messages = JavacMessages.instance(docenv().context); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
109 |
Locale locale = Locale.getDefault(); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
110 |
Printer printer = new Printer() { |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
111 |
int count; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
112 |
@Override |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
113 |
protected String localize(Locale locale, String key, Object... args) { |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
114 |
return messages.getLocalizedString(locale, key, args); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
115 |
} |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
116 |
@Override |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
117 |
protected String capturedVarId(CapturedType t, Locale locale) { |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
118 |
return "CAP#" + (++count); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
119 |
} |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
120 |
}; |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
121 |
|
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
122 |
String s = text.replaceAll("\\s+", " "); // normalize white space |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
123 |
int sp = s.indexOf(" "); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
124 |
int lparen = s.indexOf("("); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
125 |
int rparen = s.indexOf(")"); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
126 |
String seetext = (sp == -1) ? s |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
127 |
: (lparen == -1 || sp < lparen) ? s.substring(0, sp) |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
128 |
: s.substring(0, rparen + 1); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
129 |
|
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
130 |
File file = new File(holder.position().file().getAbsoluteFile().toURI().normalize()); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
131 |
|
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
132 |
StringBuilder sb = new StringBuilder(); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
133 |
sb.append("+++ ").append(file).append(": ") |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
134 |
.append(name()).append(" ").append(seetext).append(": "); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
135 |
sb.append(sym.getKind()).append(" "); |
27224
228abfa87080
8054457: Refactor Symbol kinds from small ints to an enum
emc
parents:
25874
diff
changeset
|
136 |
if (sym.kind == MTH || sym.kind == VAR) |
14541
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
137 |
sb.append(printer.visit(sym.owner, locale)).append("."); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
138 |
sb.append(printer.visit(sym, locale)); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
139 |
|
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
140 |
System.err.println(sb); |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
141 |
} |
36f9d11fc9aa
7021614: extend com.sun.source API to support parsing javadoc comments
jjg
parents:
14447
diff
changeset
|
142 |
|
10 | 143 |
/** |
144 |
* get the class name part of @see, For instance, |
|
145 |
* if the comment is @see String#startsWith(java.lang.String) . |
|
146 |
* This function returns String. |
|
147 |
* Returns null if format was not that of java reference. |
|
148 |
* Return empty string if class name was not specified.. |
|
149 |
*/ |
|
150 |
public String referencedClassName() { |
|
151 |
return where; |
|
152 |
} |
|
153 |
||
154 |
/** |
|
155 |
* get the package referenced by @see. For instance, |
|
156 |
* if the comment is @see java.lang |
|
157 |
* This function returns a PackageDocImpl for java.lang |
|
158 |
* Returns null if no known package found. |
|
159 |
*/ |
|
160 |
public PackageDoc referencedPackage() { |
|
161 |
return referencedPackage; |
|
162 |
} |
|
163 |
||
164 |
/** |
|
165 |
* get the class referenced by the class name part of @see, For instance, |
|
166 |
* if the comment is @see String#startsWith(java.lang.String) . |
|
167 |
* This function returns a ClassDocImpl for java.lang.String. |
|
168 |
* Returns null if class is not a class specified on the javadoc command line.. |
|
169 |
*/ |
|
170 |
public ClassDoc referencedClass() { |
|
171 |
return referencedClass; |
|
172 |
} |
|
173 |
||
174 |
/** |
|
175 |
* get the name of the member referenced by the prototype part of @see, |
|
176 |
* For instance, |
|
177 |
* if the comment is @see String#startsWith(java.lang.String) . |
|
178 |
* This function returns "startsWith(java.lang.String)" |
|
179 |
* Returns null if format was not that of java reference. |
|
180 |
* Return empty string if member name was not specified.. |
|
181 |
*/ |
|
182 |
public String referencedMemberName() { |
|
183 |
return what; |
|
184 |
} |
|
185 |
||
186 |
/** |
|
187 |
* get the member referenced by the prototype part of @see, |
|
188 |
* For instance, |
|
189 |
* if the comment is @see String#startsWith(java.lang.String) . |
|
190 |
* This function returns a MethodDocImpl for startsWith. |
|
191 |
* Returns null if member could not be determined. |
|
192 |
*/ |
|
193 |
public MemberDoc referencedMember() { |
|
194 |
return referencedMember; |
|
195 |
} |
|
196 |
||
197 |
||
198 |
/** |
|
199 |
* parse @see part of comment. Determine 'where' and 'what' |
|
200 |
*/ |
|
201 |
private void parseSeeString() { |
|
202 |
int len = text.length(); |
|
203 |
if (len == 0) { |
|
204 |
return; |
|
205 |
} |
|
206 |
switch (text.charAt(0)) { |
|
207 |
case '<': |
|
208 |
if (text.charAt(len-1) != '>') { |
|
209 |
docenv().warning(holder, |
|
210 |
"tag.see.no_close_bracket_on_url", |
|
211 |
name, text); |
|
212 |
} |
|
213 |
return; |
|
214 |
case '"': |
|
215 |
if (len == 1 || text.charAt(len-1) != '"') { |
|
216 |
docenv().warning(holder, |
|
217 |
"tag.see.no_close_quote", |
|
218 |
name, text); |
|
219 |
} else { |
|
220 |
// text = text.substring(1,len-1); // strip quotes |
|
221 |
} |
|
222 |
return; |
|
223 |
} |
|
224 |
||
225 |
// check that the text is one word, with possible parentheses |
|
226 |
// this part of code doesn't allow |
|
227 |
// @see <a href=.....>asfd</a> |
|
228 |
// comment it. |
|
229 |
||
230 |
// the code assumes that there is no initial white space. |
|
231 |
int parens = 0; |
|
232 |
int commentstart = 0; |
|
233 |
int start = 0; |
|
234 |
int cp; |
|
235 |
for (int i = start; i < len ; i += Character.charCount(cp)) { |
|
236 |
cp = text.codePointAt(i); |
|
237 |
switch (cp) { |
|
238 |
case '(': parens++; break; |
|
239 |
case ')': parens--; break; |
|
240 |
case '[': case ']': case '.': case '#': break; |
|
241 |
case ',': |
|
242 |
if (parens <= 0) { |
|
243 |
docenv().warning(holder, |
|
244 |
"tag.see.malformed_see_tag", |
|
245 |
name, text); |
|
246 |
return; |
|
247 |
} |
|
248 |
break; |
|
249 |
case ' ': case '\t': case '\n': case CR: |
|
250 |
if (parens == 0) { //here onwards the comment starts. |
|
251 |
commentstart = i; |
|
252 |
i = len; |
|
253 |
} |
|
254 |
break; |
|
255 |
default: |
|
256 |
if (!Character.isJavaIdentifierPart(cp)) { |
|
257 |
docenv().warning(holder, |
|
258 |
"tag.see.illegal_character", |
|
259 |
name, ""+cp, text); |
|
260 |
} |
|
261 |
break; |
|
262 |
} |
|
263 |
} |
|
264 |
if (parens != 0) { |
|
265 |
docenv().warning(holder, |
|
266 |
"tag.see.malformed_see_tag", |
|
267 |
name, text); |
|
268 |
return; |
|
269 |
} |
|
270 |
||
271 |
String seetext = ""; |
|
272 |
String labeltext = ""; |
|
273 |
||
274 |
if (commentstart > 0) { |
|
275 |
seetext = text.substring(start, commentstart); |
|
276 |
labeltext = text.substring(commentstart + 1); |
|
277 |
// strip off the white space which can be between seetext and the |
|
278 |
// actual label. |
|
279 |
for (int i = 0; i < labeltext.length(); i++) { |
|
280 |
char ch2 = labeltext.charAt(i); |
|
281 |
if (!(ch2 == ' ' || ch2 == '\t' || ch2 == '\n')) { |
|
282 |
label = labeltext.substring(i); |
|
283 |
break; |
|
284 |
} |
|
285 |
} |
|
286 |
} else { |
|
287 |
seetext = text; |
|
288 |
label = ""; |
|
289 |
} |
|
290 |
||
291 |
int sharp = seetext.indexOf('#'); |
|
292 |
if (sharp >= 0) { |
|
293 |
// class#member |
|
294 |
where = seetext.substring(0, sharp); |
|
295 |
what = seetext.substring(sharp + 1); |
|
296 |
} else { |
|
297 |
if (seetext.indexOf('(') >= 0) { |
|
298 |
docenv().warning(holder, |
|
299 |
"tag.see.missing_sharp", |
|
300 |
name, text); |
|
301 |
where = ""; |
|
302 |
what = seetext; |
|
303 |
} |
|
304 |
else { |
|
305 |
// no member specified, text names class |
|
306 |
where = seetext; |
|
307 |
what = null; |
|
308 |
} |
|
309 |
} |
|
310 |
} |
|
311 |
||
312 |
/** |
|
313 |
* Find what is referenced by the see also. If possible, sets |
|
314 |
* referencedClass and referencedMember. |
|
315 |
* |
|
316 |
* @param containingClass the class containing the comment containing |
|
317 |
* the tag. May be null, if, for example, it is a package comment. |
|
318 |
*/ |
|
319 |
private void findReferenced(ClassDocImpl containingClass) { |
|
320 |
if (where.length() > 0) { |
|
321 |
if (containingClass != null) { |
|
322 |
referencedClass = containingClass.findClass(where); |
|
323 |
} else { |
|
324 |
referencedClass = docenv().lookupClass(where); |
|
325 |
} |
|
326 |
if (referencedClass == null && holder() instanceof ProgramElementDoc) { |
|
327 |
referencedClass = docenv().lookupClass( |
|
328 |
((ProgramElementDoc) holder()).containingPackage().name() + "." + where); |
|
329 |
} |
|
330 |
||
331 |
if (referencedClass == null) { /* may just not be in this run */ |
|
332 |
// check if it's a package name |
|
333 |
referencedPackage = docenv().lookupPackage(where); |
|
334 |
return; |
|
335 |
} |
|
336 |
} else { |
|
337 |
if (containingClass == null) { |
|
338 |
docenv().warning(holder, |
|
339 |
"tag.see.class_not_specified", |
|
340 |
name, text); |
|
341 |
return; |
|
342 |
} else { |
|
343 |
referencedClass = containingClass; |
|
344 |
} |
|
345 |
} |
|
346 |
where = referencedClass.qualifiedName(); |
|
347 |
||
348 |
if (what == null) { |
|
349 |
return; |
|
350 |
} else { |
|
351 |
int paren = what.indexOf('('); |
|
352 |
String memName = (paren >= 0 ? what.substring(0, paren) : what); |
|
353 |
String[] paramarr; |
|
354 |
if (paren > 0) { |
|
355 |
// has parameter list -- should be method or constructor |
|
356 |
paramarr = new ParameterParseMachine(what. |
|
357 |
substring(paren, what.length())).parseParameters(); |
|
358 |
if (paramarr != null) { |
|
359 |
referencedMember = findExecutableMember(memName, paramarr, |
|
360 |
referencedClass); |
|
361 |
} else { |
|
362 |
referencedMember = null; |
|
363 |
} |
|
364 |
} else { |
|
365 |
// no parameter list -- should be field |
|
366 |
referencedMember = findExecutableMember(memName, null, |
|
367 |
referencedClass); |
|
368 |
FieldDoc fd = ((ClassDocImpl)referencedClass). |
|
369 |
findField(memName); |
|
370 |
// when no args given, prefer fields over methods |
|
371 |
if (referencedMember == null || |
|
372 |
(fd != null && |
|
373 |
fd.containingClass() |
|
374 |
.subclassOf(referencedMember.containingClass()))) { |
|
375 |
referencedMember = fd; |
|
376 |
} |
|
377 |
} |
|
378 |
if (referencedMember == null) { |
|
379 |
docenv().warning(holder, |
|
380 |
"tag.see.can_not_find_member", |
|
381 |
name, what, where); |
|
382 |
} |
|
383 |
} |
|
384 |
} |
|
385 |
||
386 |
private MemberDoc findReferencedMethod(String memName, String[] paramarr, |
|
387 |
ClassDoc referencedClass) { |
|
388 |
MemberDoc meth = findExecutableMember(memName, paramarr, referencedClass); |
|
389 |
if (meth == null) { |
|
22159
682da512ec17
8030253: Update langtools to use strings-in-switch
briangoetz
parents:
14541
diff
changeset
|
390 |
for (ClassDoc nestedClass : referencedClass.innerClasses()) { |
682da512ec17
8030253: Update langtools to use strings-in-switch
briangoetz
parents:
14541
diff
changeset
|
391 |
meth = findReferencedMethod(memName, paramarr, nestedClass); |
10 | 392 |
if (meth != null) { |
393 |
return meth; |
|
394 |
} |
|
395 |
} |
|
396 |
} |
|
397 |
return null; |
|
398 |
} |
|
399 |
||
400 |
private MemberDoc findExecutableMember(String memName, String[] paramarr, |
|
401 |
ClassDoc referencedClass) { |
|
23794
9437acfa99e9
8031625: javadoc problems referencing inner class constructors
bpatel
parents:
22163
diff
changeset
|
402 |
String className = referencedClass.name(); |
9437acfa99e9
8031625: javadoc problems referencing inner class constructors
bpatel
parents:
22163
diff
changeset
|
403 |
if (memName.equals(className.substring(className.lastIndexOf(".") + 1))) { |
10 | 404 |
return ((ClassDocImpl)referencedClass).findConstructor(memName, |
405 |
paramarr); |
|
406 |
} else { // it's a method. |
|
407 |
return ((ClassDocImpl)referencedClass).findMethod(memName, |
|
408 |
paramarr); |
|
409 |
} |
|
410 |
} |
|
411 |
||
412 |
// separate "int, String" from "(int, String)" |
|
413 |
// (int i, String s) ==> [0] = "int", [1] = String |
|
414 |
// (int[][], String[]) ==> [0] = "int[][]" // [1] = "String[]" |
|
415 |
class ParameterParseMachine { |
|
5010 | 416 |
static final int START = 0; |
417 |
static final int TYPE = 1; |
|
418 |
static final int NAME = 2; |
|
419 |
static final int TNSPACE = 3; // space between type and name |
|
420 |
static final int ARRAYDECORATION = 4; |
|
421 |
static final int ARRAYSPACE = 5; |
|
10 | 422 |
|
423 |
String parameters; |
|
424 |
||
8631
664f84942e74
6866185: Util.getPackageSourcePath should use lastIndexOf not indexOf and related cleanup
jjg
parents:
5520
diff
changeset
|
425 |
StringBuilder typeId; |
10 | 426 |
|
427 |
ListBuffer<String> paramList; |
|
428 |
||
429 |
ParameterParseMachine(String parameters) { |
|
430 |
this.parameters = parameters; |
|
22163 | 431 |
this.paramList = new ListBuffer<>(); |
8631
664f84942e74
6866185: Util.getPackageSourcePath should use lastIndexOf not indexOf and related cleanup
jjg
parents:
5520
diff
changeset
|
432 |
typeId = new StringBuilder(); |
10 | 433 |
} |
434 |
||
435 |
public String[] parseParameters() { |
|
436 |
if (parameters.equals("()")) { |
|
437 |
return new String[0]; |
|
438 |
} // now strip off '(' and ')' |
|
439 |
int state = START; |
|
440 |
int prevstate = START; |
|
441 |
parameters = parameters.substring(1, parameters.length() - 1); |
|
442 |
int cp; |
|
443 |
for (int index = 0; index < parameters.length(); index += Character.charCount(cp)) { |
|
444 |
cp = parameters.codePointAt(index); |
|
445 |
switch (state) { |
|
446 |
case START: |
|
447 |
if (Character.isJavaIdentifierStart(cp)) { |
|
448 |
typeId.append(Character.toChars(cp)); |
|
449 |
state = TYPE; |
|
450 |
} |
|
451 |
prevstate = START; |
|
452 |
break; |
|
453 |
case TYPE: |
|
454 |
if (Character.isJavaIdentifierPart(cp) || cp == '.') { |
|
455 |
typeId.append(Character.toChars(cp)); |
|
456 |
} else if (cp == '[') { |
|
457 |
typeId.append('['); |
|
458 |
state = ARRAYDECORATION; |
|
459 |
} else if (Character.isWhitespace(cp)) { |
|
460 |
state = TNSPACE; |
|
461 |
} else if (cp == ',') { // no name, just type |
|
462 |
addTypeToParamList(); |
|
463 |
state = START; |
|
464 |
} |
|
465 |
prevstate = TYPE; |
|
466 |
break; |
|
467 |
case TNSPACE: |
|
468 |
if (Character.isJavaIdentifierStart(cp)) { // name |
|
469 |
if (prevstate == ARRAYDECORATION) { |
|
470 |
docenv().warning(holder, |
|
471 |
"tag.missing_comma_space", |
|
472 |
name, |
|
473 |
"(" + parameters + ")"); |
|
474 |
return (String[])null; |
|
475 |
} |
|
476 |
addTypeToParamList(); |
|
477 |
state = NAME; |
|
478 |
} else if (cp == '[') { |
|
479 |
typeId.append('['); |
|
480 |
state = ARRAYDECORATION; |
|
481 |
} else if (cp == ',') { // just the type |
|
482 |
addTypeToParamList(); |
|
483 |
state = START; |
|
484 |
} // consume rest all |
|
485 |
prevstate = TNSPACE; |
|
486 |
break; |
|
487 |
case ARRAYDECORATION: |
|
488 |
if (cp == ']') { |
|
489 |
typeId.append(']'); |
|
490 |
state = TNSPACE; |
|
491 |
} else if (!Character.isWhitespace(cp)) { |
|
492 |
docenv().warning(holder, |
|
493 |
"tag.illegal_char_in_arr_dim", |
|
494 |
name, |
|
495 |
"(" + parameters + ")"); |
|
496 |
return (String[])null; |
|
497 |
} |
|
498 |
prevstate = ARRAYDECORATION; |
|
499 |
break; |
|
500 |
case NAME: |
|
501 |
if (cp == ',') { // just consume everything till ',' |
|
502 |
state = START; |
|
503 |
} |
|
504 |
prevstate = NAME; |
|
505 |
break; |
|
506 |
} |
|
507 |
} |
|
508 |
if (state == ARRAYDECORATION || |
|
509 |
(state == START && prevstate == TNSPACE)) { |
|
510 |
docenv().warning(holder, |
|
511 |
"tag.illegal_see_tag", |
|
512 |
"(" + parameters + ")"); |
|
513 |
} |
|
514 |
if (typeId.length() > 0) { |
|
515 |
paramList.append(typeId.toString()); |
|
516 |
} |
|
868 | 517 |
return paramList.toArray(new String[paramList.length()]); |
10 | 518 |
} |
519 |
||
520 |
void addTypeToParamList() { |
|
521 |
if (typeId.length() > 0) { |
|
522 |
paramList.append(typeId.toString()); |
|
523 |
typeId.setLength(0); |
|
524 |
} |
|
525 |
} |
|
526 |
} |
|
527 |
||
528 |
/** |
|
529 |
* Return the kind of this tag. |
|
530 |
*/ |
|
8631
664f84942e74
6866185: Util.getPackageSourcePath should use lastIndexOf not indexOf and related cleanup
jjg
parents:
5520
diff
changeset
|
531 |
@Override |
10 | 532 |
public String kind() { |
533 |
return "@see"; |
|
534 |
} |
|
535 |
||
536 |
/** |
|
537 |
* Return the label of the see tag. |
|
538 |
*/ |
|
539 |
public String label() { |
|
540 |
return label; |
|
541 |
} |
|
542 |
} |